@untemps/react-vocal 2.0.0-beta.6 → 2.0.0-beta.8

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +23 -5
  3. package/dist/index.es.js +233 -759
  4. package/dist/index.js +2 -4
  5. package/package.json +7 -6
  6. package/.github/workflows/publish.yml +0 -32
  7. package/.husky/commit-msg +0 -1
  8. package/.husky/pre-commit +0 -1
  9. package/.prettierignore +0 -3
  10. package/.prettierrc +0 -29
  11. package/CLAUDE.md +0 -59
  12. package/assets/icon-idle.png +0 -0
  13. package/assets/icon-listening.png +0 -0
  14. package/assets/microphone.png +0 -0
  15. package/assets/react-vocal.png +0 -0
  16. package/commitlint.config.js +0 -7
  17. package/dev/index.html +0 -24
  18. package/dev/package.json +0 -18
  19. package/dev/public/index.html +0 -24
  20. package/dev/src/index.jsx +0 -66
  21. package/dev/vite.config.js +0 -10
  22. package/dev/yarn.lock +0 -325
  23. package/dist/index.es.js.map +0 -1
  24. package/dist/index.js.map +0 -1
  25. package/dist/index.umd.js +0 -9
  26. package/dist/index.umd.js.map +0 -1
  27. package/src/components/Icon.jsx +0 -24
  28. package/src/components/Vocal.jsx +0 -261
  29. package/src/components/__tests__/Icon.test.jsx +0 -38
  30. package/src/components/__tests__/Vocal.test.jsx +0 -748
  31. package/src/components/__tests__/VocalWithMockedUseVocal.test.jsx +0 -38
  32. package/src/components/__tests__/__snapshots__/Icon.test.jsx.snap +0 -21
  33. package/src/components/__tests__/__snapshots__/Vocal.test.jsx.snap +0 -28
  34. package/src/hooks/__tests__/useCommands.test.js +0 -115
  35. package/src/hooks/__tests__/useTimeout.test.js +0 -69
  36. package/src/hooks/__tests__/useVocal.test.js +0 -207
  37. package/src/hooks/useCommands.js +0 -75
  38. package/src/hooks/useTimeout.js +0 -21
  39. package/src/hooks/useVocal.js +0 -56
  40. package/src/index.js +0 -7
  41. package/vite.config.js +0 -36
  42. package/vitest.setup.js +0 -83
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let l=require(`react`);l=c(l);var u=function(e,t,n){return e(n={path:t,exports:{},require:function(e,t){return function(){throw Error(`Dynamic requires are not currently supported by @rollup/plugin-commonjs`)}(t==null&&n.path)}},n.exports),n.exports}((function(e){var t=function(e){var t=Object.prototype,n=t.hasOwnProperty,r=typeof Symbol==`function`?Symbol:{},i=r.iterator||`@@iterator`,a=r.asyncIterator||`@@asyncIterator`,o=r.toStringTag||`@@toStringTag`;function s(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{s({},``)}catch{s=function(e,t,n){return e[t]=n}}function c(e,t,n,r){var i=t&&t.prototype instanceof d?t:d,a=Object.create(i.prototype);return a._invoke=function(e,t,n){var r=`suspendedStart`;return function(i,a){if(r===`executing`)throw Error(`Generator is already running`);if(r===`completed`){if(i===`throw`)throw a;return T()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=b(o,n);if(s){if(s===u)continue;return s}}if(n.method===`next`)n.sent=n._sent=n.arg;else if(n.method===`throw`){if(r===`suspendedStart`)throw r=`completed`,n.arg;n.dispatchException(n.arg)}else n.method===`return`&&n.abrupt(`return`,n.arg);r=`executing`;var c=l(e,t,n);if(c.type===`normal`){if(r=n.done?`completed`:`suspendedYield`,c.arg===u)continue;return{value:c.arg,done:n.done}}c.type===`throw`&&(r=`completed`,n.method=`throw`,n.arg=c.arg)}}}(e,n,new C(r||[])),a}function l(e,t,n){try{return{type:`normal`,arg:e.call(t,n)}}catch(e){return{type:`throw`,arg:e}}}e.wrap=c;var u={};function d(){}function f(){}function p(){}var m={};m[i]=function(){return this};var h=Object.getPrototypeOf,g=h&&h(h(w([])));g&&g!==t&&n.call(g,i)&&(m=g);var _=p.prototype=d.prototype=Object.create(m);function v(e){[`next`,`throw`,`return`].forEach((function(t){s(e,t,(function(e){return this._invoke(t,e)}))}))}function y(e,t){var r;this._invoke=function(i,a){function o(){return new t((function(r,o){(function r(i,a,o,s){var c=l(e[i],e,a);if(c.type!==`throw`){var u=c.arg,d=u.value;return d&&typeof d==`object`&&n.call(d,`__await`)?t.resolve(d.__await).then((function(e){r(`next`,e,o,s)}),(function(e){r(`throw`,e,o,s)})):t.resolve(d).then((function(e){u.value=e,o(u)}),(function(e){return r(`throw`,e,o,s)}))}s(c.arg)})(i,a,r,o)}))}return r=r?r.then(o,o):o()}}function b(e,t){var n=e.iterator[t.method];if(n===void 0){if(t.delegate=null,t.method===`throw`){if(e.iterator.return&&(t.method=`return`,t.arg=void 0,b(e,t),t.method===`throw`))return u;t.method=`throw`,t.arg=TypeError(`The iterator does not provide a 'throw' method`)}return u}var r=l(n,e.iterator,t.arg);if(r.type===`throw`)return t.method=`throw`,t.arg=r.arg,t.delegate=null,u;var i=r.arg;return i?i.done?(t[e.resultName]=i.value,t.next=e.nextLoc,t.method!==`return`&&(t.method=`next`,t.arg=void 0),t.delegate=null,u):i:(t.method=`throw`,t.arg=TypeError(`iterator result is not an object`),t.delegate=null,u)}function x(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function S(e){var t=e.completion||{};t.type=`normal`,delete t.arg,e.completion=t}function C(e){this.tryEntries=[{tryLoc:`root`}],e.forEach(x,this),this.reset(!0)}function w(e){if(e){var t=e[i];if(t)return t.call(e);if(typeof e.next==`function`)return e;if(!isNaN(e.length)){var r=-1,a=function t(){for(;++r<e.length;)if(n.call(e,r))return t.value=e[r],t.done=!1,t;return t.value=void 0,t.done=!0,t};return a.next=a}}return{next:T}}function T(){return{value:void 0,done:!0}}return f.prototype=_.constructor=p,p.constructor=f,f.displayName=s(p,o,`GeneratorFunction`),e.isGeneratorFunction=function(e){var t=typeof e==`function`&&e.constructor;return!!t&&(t===f||(t.displayName||t.name)===`GeneratorFunction`)},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,p):(e.__proto__=p,s(e,o,`GeneratorFunction`)),e.prototype=Object.create(_),e},e.awrap=function(e){return{__await:e}},v(y.prototype),y.prototype[a]=function(){return this},e.AsyncIterator=y,e.async=function(t,n,r,i,a){a===void 0&&(a=Promise);var o=new y(c(t,n,r,i),a);return e.isGeneratorFunction(n)?o:o.next().then((function(e){return e.done?e.value:o.next()}))},v(_),s(_,o,`Generator`),_[i]=function(){return this},_.toString=function(){return`[object Generator]`},e.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var r=t.pop();if(r in e)return n.value=r,n.done=!1,n}return n.done=!0,n}},e.values=w,C.prototype={constructor:C,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method=`next`,this.arg=void 0,this.tryEntries.forEach(S),!e)for(var t in this)t.charAt(0)===`t`&&n.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=void 0)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if(e.type===`throw`)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function r(n,r){return o.type=`throw`,o.arg=e,t.next=n,r&&(t.method=`next`,t.arg=void 0),!!r}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],o=a.completion;if(a.tryLoc===`root`)return r(`end`);if(a.tryLoc<=this.prev){var s=n.call(a,`catchLoc`),c=n.call(a,`finallyLoc`);if(s&&c){if(this.prev<a.catchLoc)return r(a.catchLoc,!0);if(this.prev<a.finallyLoc)return r(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return r(a.catchLoc,!0)}else{if(!c)throw Error(`try statement without catch or finally`);if(this.prev<a.finallyLoc)return r(a.finallyLoc)}}}},abrupt:function(e,t){for(var r=this.tryEntries.length-1;r>=0;--r){var i=this.tryEntries[r];if(i.tryLoc<=this.prev&&n.call(i,`finallyLoc`)&&this.prev<i.finallyLoc){var a=i;break}}a&&(e===`break`||e===`continue`)&&a.tryLoc<=t&&t<=a.finallyLoc&&(a=null);var o=a?a.completion:{};return o.type=e,o.arg=t,a?(this.method=`next`,this.next=a.finallyLoc,u):this.complete(o)},complete:function(e,t){if(e.type===`throw`)throw e.arg;return e.type===`break`||e.type===`continue`?this.next=e.arg:e.type===`return`?(this.rval=this.arg=e.arg,this.method=`return`,this.next=`end`):e.type===`normal`&&t&&(this.next=t),u},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),S(n),u}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if(r.type===`throw`){var i=r.arg;S(n)}return i}}throw Error(`illegal catch attempt`)},delegateYield:function(e,t,n){return this.delegate={iterator:w(e),resultName:t,nextLoc:n},this.method===`next`&&(this.arg=void 0),u}},e}(e.exports);try{regeneratorRuntime=t}catch{Function(`r`,`regeneratorRuntime = r`)(t)}}));function d(e,t,n,r,i,a,o){try{var s=e[a](o),c=s.value}catch(e){n(e);return}s.done?t(c):Promise.resolve(c).then(r,i)}var f=function(e){return function(){var t=this,n=arguments;return new Promise((function(r,i){var a=e.apply(t,n);function o(e){d(a,r,i,o,s,`next`,e)}function s(e){d(a,r,i,o,s,`throw`,e)}o(void 0)}))}},p=function(e){if(Array.isArray(e))return e},m=function(e,t){if(typeof Symbol<`u`&&Symbol.iterator in Object(e)){var n=[],r=!0,i=!1,a=void 0;try{for(var o,s=e[Symbol.iterator]();!(r=(o=s.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{r||s.return==null||s.return()}finally{if(i)throw a}}return n}},h=function(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r},g=function(e,t){if(e){if(typeof e==`string`)return h(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?h(e,t):void 0}},_=function(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
2
- In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)},v=function(e,t){return p(e)||m(e,t)||g(e,t)||_()},y=function(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)};function b(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,`value`in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var x=function(e,t,n){return t&&b(e.prototype,t),n&&b(e,n),e},S=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},C=function(){return!!navigator.permissions},w=function(){return!!navigator.mediaDevices};function T(e,t,n,r,i,a,o){try{var s=e[a](o),c=s.value}catch(e){n(e);return}s.done?t(c):Promise.resolve(c).then(r,i)}function E(e){return function(){var t=this,n=arguments;return new Promise((function(r,i){var a=e.apply(t,n);function o(e){T(a,r,i,o,s,`next`,e)}function s(e){T(a,r,i,o,s,`throw`,e)}o(void 0)}))}}function D(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(typeof Symbol<`u`&&Symbol.iterator in Object(e)){var n=[],r=!0,i=!1,a=void 0;try{for(var o,s=e[Symbol.iterator]();!(r=(o=s.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{r||s.return==null||s.return()}finally{if(i)throw a}}return n}}(e,t)||function(e,t){if(e){if(typeof e==`string`)return O(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?O(e,t):void 0}}(e,t)||function(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
3
- In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}()}function O(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var k=function(){var e=E(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(`return`,new Promise(function(){var e=E(regeneratorRuntime.mark((function e(n,r){var i,a;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return C()||r(new DOMException(`Navigator API: permissions not supported`,`NOT_SUPPORTED_ERR`)),e.prev=1,e.next=4,navigator.permissions.query({name:t});case 4:i=e.sent,a=function e(t){i.removeEventListener(`change`,e),A(t.target.state,n,r)},i.addEventListener(`change`,a),A(i.state,n,r),e.next=13;break;case 10:e.prev=10,e.t0=e.catch(1),r(e.t0);case 13:case`end`:return e.stop()}}),e,null,[[1,10]])})));return function(t,n){return e.apply(this,arguments)}}()));case 1:case`end`:return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),A=function(e,t,n){switch(e){case`denied`:n(new DOMException(`Permission denied`,`NOT_ALLOWED_ERR`));break;default:t(e)}},j=function(){var e=E(regeneratorRuntime.mark((function e(t,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(`return`,new Promise(function(){var e=E(regeneratorRuntime.mark((function e(r,i){var a,o,s;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return C()&&w()||i(new DOMException(`Navigator API: permissions or Navigator API: mediaDevices not supported`,`NOT_SUPPORTED_ERR`)),e.prev=1,e.t0=Promise,e.next=5,k(t);case 5:return e.t1=e.sent,e.next=8,navigator.mediaDevices.getUserMedia(n);case 8:return e.t2=e.sent,e.t3=[e.t1,e.t2],e.next=12,e.t0.all.call(e.t0,e.t3);case 12:a=e.sent,o=D(a,2),s=o[1],r(s),e.next=21;break;case 18:e.prev=18,e.t4=e.catch(1),i(e.t4);case 21:case`end`:return e.stop()}}),e,null,[[1,18]])})));return function(t,n){return e.apply(this,arguments)}}()));case 1:case`end`:return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}();function M(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function N(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?M(Object(n),!0).forEach((function(t){S(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):M(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var P=function(){function e(t){var n=this;y(this,e),S(this,`_instance`,null),S(this,`_listeners`,null);var r=e._resolveSpeechRecognition();if(!r)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);this._instance=new r,this._listeners={},Object.entries(N(N({},e.defaultOptions),t||{})).forEach((function(t){var r=v(t,2),i=r[0],a=r[1];if(i===`grammars`&&!a){var o=e._resolveSpeechGrammarList();o&&(a=new o)}n._instance[i]=a}))}var t;return x(e,null,[{key:`isSupported`,get:function(){return!!e._resolveSpeechRecognition()&&!!C()&&!!w()},set:function(e){throw Error(`You cannot set isSupported directly.`)}}]),x(e,[{key:`start`,value:(t=f(u.mark((function e(){var t;return u.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!this._instance){e.next=14;break}return e.prev=1,e.next=4,j(`microphone`,{audio:!0});case 4:if(e.sent){e.next=7;break}throw Error(`Unable to retrieve the stream from media device`);case 7:this._instance.start(),e.next=14;break;case 10:e.prev=10,e.t0=e.catch(1),(t=this._listeners.error)&&t(e.t0);case 14:return e.abrupt(`return`,this);case 15:case`end`:return e.stop()}}),e,this,[[1,10]])}))),function(){return t.apply(this,arguments)})},{key:`stop`,value:function(){return this._instance&&this._instance.stop(),this}},{key:`abort`,value:function(){return this._instance&&this._instance.abort(),this}},{key:`addEventListener`,value:function(t,n){var r=this;if(this._instance&&this._includesEventType(t)){this._listeners[t]&&this.removeEventListener(t);var i=function(i){var a=[];t===e.eventTypes.RESULT&&i.results&&i.results.length>0&&a.push(i.results[0][0].transcript),n&&n.apply(r,[i].concat(a))};this._instance.addEventListener(t,i),this._listeners[t]=i}return this}},{key:`removeEventListener`,value:function(e){var t=this._listeners[e];return this._instance.removeEventListener(e,t),delete this._listeners[e],this}},{key:`cleanup`,value:function(){var e=this;return this.stop(),Object.keys(this._listeners).forEach((function(t){return e.removeEventListener(t)})),this._instance=null,this}},{key:`_includesEventType`,value:function(t){return!!Object.values(e.eventTypes).find((function(e){return e===t}))}},{key:`instance`,get:function(){return this._instance},set:function(e){throw Error(`You cannot set instance directly.`)}}],[{key:`_resolveSpeechRecognition`,value:function(){return window.SpeechRecognition||window.webkitSpeechRecognition||window.mozSpeechRecognition||window.msSpeechRecognition}},{key:`_resolveSpeechGrammarList`,value:function(){return window.SpeechGrammarList||window.webkitSpeechGrammarList||window.mozSpeechGrammarList||window.msSpeechGrammarList}}]),e}();S(P,`defaultOptions`,{grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1,serviceURI:null}),S(P,`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`});var F=e=>typeof e==`function`,I=(e=`en-US`,t=null,n=1,r=!1,i=null)=>{let a=(0,l.useRef)(null);return(0,l.useEffect)(()=>{if(P.isSupported)return a.current=i||new P({lang:e,grammars:t,maxAlternatives:n,continuous:r}),()=>{a.current.abort(),a.current.cleanup()}},[e,t,n,r,i]),[a,{start:(0,l.useCallback)(()=>{a.current&&a.current.start()},[]),stop:(0,l.useCallback)(()=>{a.current&&a.current.stop()},[]),abort:(0,l.useCallback)(()=>{a.current&&a.current.abort()},[]),subscribe:(0,l.useCallback)((e,t)=>{a.current&&a.current.addEventListener(e,t)},[]),unsubscribe:(0,l.useCallback)((e,t)=>{a.current&&a.current.removeEventListener(e,t)},[]),clean:(0,l.useCallback)(()=>{a.current&&a.current.cleanup()},[])}]},L=(e,t=0)=>{let n=(0,l.useRef)(-1),r=(0,l.useCallback)(()=>{clearTimeout(n.current),n.current=-1},[]),i=(0,l.useCallback)(()=>{r(),n.current=setTimeout(e,t)},[e,t,r]);return(0,l.useEffect)(()=>r,[r]),[i,r]},ee=(e,t=.4)=>{let n=(0,l.useMemo)(()=>e?Object.entries(e).reduce((e,[t,n])=>({...e,[t.toLowerCase()]:n}),{}):{},[e]),r=(0,l.useMemo)(()=>Object.keys(n),[n]),i=(0,l.useMemo)(()=>r.some(e=>e.includes(` `)),[r]),a=(0,l.useRef)(null);return(0,l.useEffect)(()=>{if(!i){a.current=null;return}import(`fuse.js`).then(e=>{a.current=new(e.default??e)(r,{includeScore:!0,ignoreLocation:!0})}).catch(()=>{process.env.NODE_ENV!==`production`&&console.warn(`[react-vocal] fuse.js is not installed. Phrase command keys will fall back to exact matching. Install fuse.js to enable fuzzy matching: npm install fuse.js`)})},[i,r]),e=>{if(!r.length)return null;if(!i){let t=e.trim().split(/\s+/),r=t.length>1?t:[e.trim()];for(let e of r){let t=e.toLowerCase();if(t in n)return n[t]?.(e,t)}return null}let o=a.current;if(o){let r=o.search(e).filter(e=>e.score<t);if(r?.length){let t=r[0].item.toLowerCase();return n[t]?.(e,t)}}else{let t=e.toLowerCase(),i=r.find(e=>t.includes(e)||e.includes(t));if(i)return n[i]?.(e,i)}return null}},R=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),z=o((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){N||(N=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,`key`,{get:n,configurable:!0})}function l(){var e=t(this.type);return P[e]||(P[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,`ref`,{enumerable:!1,value:null}):Object.defineProperty(e,`ref`,{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,`validated`,{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,`_debugInfo`,{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,`_debugStack`,{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,`_debugTask`,{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(j(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,L[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let l=require(`react`);l=c(l);var u=()=>!!navigator.permissions,d=()=>!!navigator.mediaDevices,f=async(e,t,{signal:n}={})=>{if(!u()||!d())throw new DOMException(`Navigator API: permissions or Navigator API: mediaDevices not supported`,`NOT_SUPPORTED_ERR`);if(n?.throwIfAborted(),(await navigator.permissions.query({name:e})).state===`denied`)throw new DOMException(`Permission denied`,`NOT_ALLOWED_ERR`);n?.throwIfAborted();let r=navigator.mediaDevices.getUserMedia(t);if(!n)return r;let i,a=new Promise((e,t)=>{i=()=>t(n.reason),n.addEventListener(`abort`,i,{once:!0})});return Promise.race([r,a]).finally(()=>{n.removeEventListener(`abort`,i)})},p={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`},m=1e3,h=new Set([`not-allowed`,`service-not-allowed`,`audio-capture`]),g={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1},_=()=>{if(!(typeof window>`u`))return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition},v=()=>window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList,y=e=>e.reduce((e,t)=>(t.confidence??0)>(e.confidence??0)?t:e),b=e=>{let t=e.slice();return Object.defineProperty(t,`isFinal`,{value:!0}),Object.defineProperty(t,`item`,{value:e=>t[e]}),t},x=e=>{let t=e.slice();return Object.defineProperty(t,`item`,{value:e=>t[e]}),t},S=e=>Object.values(p).includes(e),C=e=>`Unknown event type "${e}". Valid types are: ${Object.values(p).join(`, `)}.`,w=()=>!!_()&&!!u()&&!!d(),T=e=>{let t=_();if(!t)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);let n=new t,r={},i=!1,a=!1,o=0,s=null,c=!1,l=[],u={...g,...e??{}};if(n.lang=u.lang,n.continuous=u.continuous,n.interimResults=u.interimResults,n.maxAlternatives=u.maxAlternatives,u.grammars)n.grammars=u.grammars;else{let e=v();n.grammars=e?new e:null}let d=()=>{s!==null&&(clearTimeout(s),s=null),c=!1},w=()=>!!n&&!a&&n.continuous,T=()=>{s=null;try{n.start(),o=Date.now()}catch{c=!1,i=!1}},E=()=>{let e=l;if(l=[],e.length===0||!r[p.RESULT]?.length)return;let t=e.map(e=>y(Array.from(e)).transcript).join(` `).trim(),n=Object.assign(new Event(p.RESULT),{resultIndex:0,results:x(e)});[...r[p.RESULT]].forEach(({callback:e})=>{e(n,t,[t])})},D=[[p.END,e=>{if(w()){let t=Math.max(0,m-(Date.now()-o));c=!0,s=setTimeout(T,t),e.stopImmediatePropagation();return}E(),i=!1}],[p.START,e=>{c&&(e.stopImmediatePropagation(),queueMicrotask(()=>{c=!1}))}],[p.ERROR,e=>{h.has(e.error)&&(a=!0,d(),i=!1)}],[p.RESULT,e=>{if(!u.continuous)return;let t=e,n=t.results?.[t.resultIndex];n?.isFinal&&l.push(b(Array.from(n)))}]];D.forEach(([e,t])=>n.addEventListener(e,t));let O=async({signal:e}={})=>{if(n)try{let t=await f(`microphone`,{audio:!0},{signal:e});if(e?.aborted||!n)return;if(!t)throw Error(`Unable to retrieve the stream from media device`);a=!1,l=[],n.start(),i=!0,o=Date.now()}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;throw e}},k=()=>{n&&(a=!0,d(),n.stop(),i=!1)},A=()=>{n&&(a=!0,d(),l=[],n.abort(),i=!1)},j=(e,t)=>{if(!S(e))throw Error(C(e));if(!n)return;let i=n=>{if(c&&(e===p.END||e===p.START))return;if(e!==p.RESULT){t(n);return}let r=n;if(!(r.results?.length>0)||r.resultIndex>=r.results.length){t(n);return}let i=r.results[r.resultIndex];if(u.continuous&&i.isFinal)return;let a=Array.from(i);t(n,y(a).transcript,a.map(e=>e.transcript))};n.addEventListener(e,i),r[e]||(r[e]=[]),r[e].push({callback:t,handler:i})},M=(e,t)=>{if(!S(e))throw Error(C(e));if(!(!n||!r[e]))if(t!==void 0){let i=r[e].findIndex(e=>e.callback===t);i!==-1&&(n.removeEventListener(e,r[e][i].handler),r[e].splice(i,1),r[e].length===0&&delete r[e])}else r[e].forEach(({handler:t})=>n.removeEventListener(e,t)),delete r[e]};return{get isRecording(){return i},start:O,stop:k,abort:A,on:j,off:M,cleanup:()=>{k(),Object.keys(r).forEach(e=>M(e)),D.forEach(([e,t])=>n?.removeEventListener(e,t)),n=null}}},E=e=>typeof e==`function`,D=(e=`en-US`,t=null,n=1,r=!1,i=null)=>{let a=(0,l.useRef)(null),[o,s]=(0,l.useState)(!1),c=(0,l.useMemo)(()=>w(),[]);return(0,l.useEffect)(()=>{if(c){let o=i||T({lang:e,grammars:t,maxAlternatives:n,continuous:r});a.current=o;let c=()=>s(!0),l=()=>s(!1);return o.on(`start`,c),o.on(`end`,l),o.on(`error`,l),()=>{o.off(`start`,c),o.off(`end`,l),o.off(`error`,l),o.abort(),o.cleanup(),s(!1)}}},[e,t,n,r,i,c]),[a,{start:(0,l.useCallback)(e=>{if(a.current)return s(!0),a.current.start(e)},[]),stop:(0,l.useCallback)(()=>{a.current&&a.current.stop()},[]),abort:(0,l.useCallback)(()=>{a.current&&a.current.abort()},[]),subscribe:(0,l.useCallback)((e,t)=>{a.current&&a.current.on(e,t)},[]),unsubscribe:(0,l.useCallback)((e,t)=>{a.current&&a.current.off(e,t)},[]),clean:(0,l.useCallback)(()=>{a.current&&a.current.cleanup()},[]),isRecording:o}]},O=(e,t=0)=>{let n=(0,l.useRef)(-1),r=(0,l.useCallback)(()=>{clearTimeout(n.current),n.current=-1},[]),i=(0,l.useCallback)(()=>{r(),n.current=setTimeout(e,t)},[e,t,r]);return(0,l.useEffect)(()=>r,[r]),[i,r]},k=(e,t=.4)=>{let n=(0,l.useMemo)(()=>e?Object.entries(e).reduce((e,[t,n])=>({...e,[t.toLowerCase()]:n}),{}):{},[e]),r=(0,l.useMemo)(()=>Object.keys(n),[n]),i=(0,l.useMemo)(()=>r.some(e=>e.includes(` `)),[r]),a=(0,l.useRef)(null);return(0,l.useEffect)(()=>{if(!i){a.current=null;return}import(`fuse.js`).then(e=>{a.current=new(e.default??e)(r,{includeScore:!0,ignoreLocation:!0})}).catch(()=>{process.env.NODE_ENV!==`production`&&console.warn(`[react-vocal] fuse.js is not installed. Phrase command keys will fall back to exact matching. Install fuse.js to enable fuzzy matching: npm install fuse.js`)})},[i,r]),e=>{if(!r.length)return null;if(!i){let t=e.trim().split(/\s+/),r=t.length>1?t:[e.trim()];for(let e of r){let t=e.toLowerCase();if(t in n)return n[t]?.(e,t)}return null}let o=a.current;if(o){let r=o.search(e).filter(e=>e.score<t);if(r?.length){let t=r[0].item.toLowerCase();return n[t]?.(e,t)}}else{let t=e.toLowerCase(),i=r.find(e=>t.includes(e)||e.includes(t));if(i)return n[i]?.(e,i)}return null}},A=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),j=o((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){N||(N=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,`key`,{get:n,configurable:!0})}function l(){var e=t(this.type);return P[e]||(P[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,`ref`,{enumerable:!1,value:null}):Object.defineProperty(e,`ref`,{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,`validated`,{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,`_debugInfo`,{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,`_debugStack`,{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,`_debugTask`,{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(j(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,L[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
4
2
  let props = %s;
5
3
  <%s {...props} />
6
4
  React keys must be passed directly to JSX without using spread:
7
5
  let props = %s;
8
- <%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require(`react`),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),B=o(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=R():t.exports=z()}))(),te=({color:e=`black`,activeColor:t=`red`,isActive:n=!1})=>(0,B.jsx)(`svg`,{"data-testid":`__icon-root__`,xmlns:`http://www.w3.org/2000/svg`,width:`100%`,height:`100%`,viewBox:`0 0 24 24`,children:(0,B.jsxs)(`g`,{children:[(0,B.jsx)(`path`,{"data-testid":`__icon-path__`,fill:e,d:`M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z`}),n&&(0,B.jsx)(`circle`,{"data-testid":`__icon-active__`,fill:t,cx:`16`,cy:`4`,r:`4`})]})}),ne=(e,t)=>{for(let{alternatives:n}of e)for(let e of n)if(t(e)!==null)return},V=({children:e,commands:t=null,lang:n=`en-US`,grammars:r=null,timeout:i=3e3,silenceTimeout:a=null,precision:o=.4,maxAlternatives:s=1,continuous:c=!1,ariaLabel:u=`start recognition`,style:d=null,className:f=null,outlineStyle:p=`2px solid`,onStart:m=null,onEnd:h=null,onSpeechStart:g=null,onSpeechEnd:_=null,onResult:v=null,onError:y=null,onNoMatch:b=null,__rsInstance:x})=>{let S=(0,l.useRef)(null),[C,w]=(0,l.useState)(!1),[,{start:T,stop:E,subscribe:D,unsubscribe:O}]=I(n,r,s,c,x),k=ee(t,o),A=(0,l.useRef)({});A.current={onStart:m,onEnd:h,onSpeechStart:g,onSpeechEnd:_,onResult:v,onError:y,onNoMatch:b};let j=(0,l.useRef)(c);j.current=c;let M=(0,l.useRef)({transcript:``,event:null}),N=(0,l.useRef)(k);N.current=k;let R=(0,l.useRef)(null),z=(0,l.useRef)(null),V=(0,l.useRef)(a);V.current=a;let H=(0,l.useCallback)(()=>z.current?.(),[]),[U,W]=L(H,i),[G,K]=L(H,a??0),q=(0,l.useCallback)(()=>{try{w(!1),E()}catch(e){A.current.onError?.(e),R.current?.()}},[E]),J=(0,l.useCallback)(e=>{U(),A.current.onStart?.(e)},[U]),Y=(0,l.useCallback)(e=>{W(),A.current.onSpeechStart?.(e)},[W]),re=(0,l.useCallback)(e=>{U(),A.current.onSpeechEnd?.(e)},[U]),ie=(0,l.useCallback)(e=>{let t=Array.from(e?.results??[],e=>{let t={confidence:-1/0,transcript:``},n=[];for(let r=0;r<e.length;r++){let i=e[r];n.push(i.transcript??``),(i.confidence===void 0||i.confidence>t.confidence)&&(t=i)}return{best:t.transcript??``,alternatives:n}}),n=t.map(e=>e.best).join(``);W(),j.current?(M.current.transcript=n,M.current.event=e,V.current>0&&G()):(ne(t,N.current),q(),A.current.onResult?.(n,e))},[W,G,q]),X=(0,l.useCallback)(e=>{q(),A.current.onError?.(e)},[q]),ae=(0,l.useCallback)(e=>{W(),q(),A.current.onNoMatch?.(e)},[W,q]),Z=(0,l.useCallback)(e=>{W(),K();try{q(),R.current?.(),j.current&&M.current.transcript&&(A.current.onResult?.(M.current.transcript,M.current.event),M.current.transcript=``,M.current.event=null)}finally{A.current.onEnd?.(e)}},[W,K,q]);z.current=Z;let Q=(0,l.useMemo)(()=>({start:J,end:Z,speechstart:Y,speechend:re,result:ie,error:X,nomatch:ae}),[J,Z,Y,re,ie,X,ae]);R.current=()=>Object.entries(Q).forEach(([e,t])=>O?.(e,t));let $=(0,l.useCallback)(()=>{try{M.current.transcript=``,M.current.event=null,K(),w(!0),Object.entries(Q).forEach(([e,t])=>D(e,t)),T()}catch(e){X(e)}},[Q,D,T,K,X]),oe=()=>{!f&&p&&(S.current.style.outline=p)},se=()=>{!f&&p&&(S.current.style.outline=`none`)};return P.isSupported?F(e)?e($,q,C):(0,l.isValidElement)(e)?(0,l.cloneElement)(e,{...!C&&{onClick:$}}):(0,B.jsx)(`button`,{"data-testid":`__vocal-root__`,ref:S,"aria-label":u,"aria-pressed":C,style:f?null:{width:24,height:24,backgroundColor:`transparent`,border:`none`,padding:0,cursor:!c&&C?`default`:`pointer`,...d},className:f,onFocus:oe,onBlur:se,onClick:C?q:$,children:(0,B.jsx)(te,{isActive:C,color:`#aaa`})}):null},H=P.isSupported,U=V;exports.default=U,exports.isSupported=H,exports.useVocal=I;
6
+ <%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require(`react`),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),M=o(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=A():t.exports=j()}))(),N=({color:e=`black`,activeColor:t=`red`,isActive:n=!1})=>(0,M.jsx)(`svg`,{"data-testid":`__icon-root__`,xmlns:`http://www.w3.org/2000/svg`,width:`100%`,height:`100%`,viewBox:`0 0 24 24`,children:(0,M.jsxs)(`g`,{children:[(0,M.jsx)(`path`,{"data-testid":`__icon-path__`,fill:e,d:`M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z`}),n&&(0,M.jsx)(`circle`,{"data-testid":`__icon-active__`,fill:t,cx:`16`,cy:`4`,r:`4`})]})}),P=(e,t)=>{for(let n of e)for(let e of n)if(t(e.transcript??``)!==null)return},F=({children:e,commands:t=null,lang:n=`en-US`,grammars:r=null,timeout:i=3e3,silenceTimeout:a=null,precision:o=.4,maxAlternatives:s=1,continuous:c=!1,ariaLabel:u=`start recognition`,style:d=null,className:f=null,outlineStyle:p=`2px solid`,onStart:m=null,onEnd:h=null,onSpeechStart:g=null,onSpeechEnd:_=null,onResult:v=null,onError:y=null,onNoMatch:b=null,signal:x=null,__rsInstance:S})=>{let C=(0,l.useRef)(null),T=(0,l.useMemo)(()=>w(),[]),[,{start:A,stop:j,subscribe:F,unsubscribe:I,isRecording:L}]=D(n,r,s,c,S),R=k(t,o),z=(0,l.useRef)({});z.current={onStart:m,onEnd:h,onSpeechStart:g,onSpeechEnd:_,onResult:v,onError:y,onNoMatch:b};let B=(0,l.useRef)(c);B.current=c;let V=(0,l.useRef)(R);V.current=R;let H=(0,l.useRef)(null),U=(0,l.useRef)(null),W=(0,l.useRef)(!1),G=(0,l.useRef)(a);G.current=a;let ee=(0,l.useCallback)(()=>U.current?.(),[]),[K,q]=O(ee,i),[te,J]=O(ee,a??0),Y=(0,l.useCallback)(()=>{try{j()}catch(e){z.current.onError?.(e),H.current?.()}},[j]),ne=(0,l.useCallback)(e=>{K(),z.current.onStart?.(e)},[K]),re=(0,l.useCallback)(e=>{q(),z.current.onSpeechStart?.(e)},[q]),ie=(0,l.useCallback)(e=>{K(),B.current&&G.current>0&&te(),z.current.onSpeechEnd?.(e)},[K,te]),ae=(0,l.useCallback)((e,t)=>{q(),B.current||(P(e?.results??[],V.current),Y()),z.current.onResult?.(t,e)},[q,Y]),X=(0,l.useCallback)(e=>{Y(),z.current.onError?.(e)},[Y]),oe=(0,l.useCallback)(e=>{q(),Y(),z.current.onNoMatch?.(e)},[q,Y]),Z=(0,l.useCallback)(e=>{if(!W.current){W.current=!0,q(),J();try{Y(),H.current?.()}finally{W.current=!1,z.current.onEnd?.(e)}}},[q,J,Y]);U.current=Z;let Q=(0,l.useMemo)(()=>({start:ne,end:Z,speechstart:re,speechend:ie,result:ae,error:X,nomatch:oe}),[ne,Z,re,ie,ae,X,oe]);H.current=()=>Object.entries(Q).forEach(([e,t])=>I?.(e,t));let $=(0,l.useCallback)(()=>{try{J(),Object.entries(Q).forEach(([e,t])=>F(e,t)),A({signal:x})?.catch?.(X)}catch(e){X(e)}},[Q,F,A,J,X,x]),se=()=>{!f&&p&&(C.current.style.outline=p)},ce=()=>{!f&&p&&(C.current.style.outline=`none`)};return T?E(e)?e($,Y,L):(0,l.isValidElement)(e)?(0,l.cloneElement)(e,{...!L&&{onClick:$}}):(0,M.jsx)(`button`,{"data-testid":`__vocal-root__`,ref:C,"aria-label":u,"aria-pressed":L,style:f?null:{width:24,height:24,backgroundColor:`transparent`,border:`none`,padding:0,cursor:!c&&L?`default`:`pointer`,...d},className:f,onFocus:se,onBlur:ce,onClick:L?Y:$,children:(0,M.jsx)(N,{isActive:L,color:`#aaa`})}):null};exports.default=F,exports.isSupported=w,exports.useVocal=D;
9
7
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@untemps/react-vocal",
3
- "version": "2.0.0-beta.6",
3
+ "version": "2.0.0-beta.8",
4
4
  "author": "Vincent Le Badezet <v.lebadezet@untemps.net>",
5
5
  "repository": "git@github.com:untemps/react-vocal.git",
6
6
  "license": "MIT",
@@ -20,6 +20,11 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
+ "files": [
24
+ "dist/index.js",
25
+ "dist/index.es.js",
26
+ "CHANGELOG.md"
27
+ ],
23
28
  "main": "dist/index.js",
24
29
  "module": "dist/index.es.js",
25
30
  "engines": {
@@ -58,7 +63,7 @@
58
63
  }
59
64
  },
60
65
  "dependencies": {
61
- "@untemps/vocal": "^1.3.0"
66
+ "@untemps/vocal": "^2.0.1"
62
67
  },
63
68
  "release": {
64
69
  "branches": [
@@ -95,10 +100,6 @@
95
100
  {
96
101
  "path": "dist/index.es.js",
97
102
  "label": "ES distribution"
98
- },
99
- {
100
- "path": "dist/index.umd.js",
101
- "label": "UMD distribution"
102
103
  }
103
104
  ]
104
105
  }
@@ -1,32 +0,0 @@
1
- name: "Publish package"
2
- on:
3
- push:
4
- branches:
5
- - main
6
- - beta
7
- permissions:
8
- contents: write
9
- id-token: write
10
- pull-requests: write
11
- issues: write
12
- jobs:
13
- release:
14
- runs-on: ubuntu-latest
15
- env:
16
- HUSKY: '0'
17
- steps:
18
- - uses: actions/checkout@v6
19
- with:
20
- fetch-depth: 0
21
- - uses: actions/setup-node@v6
22
- with:
23
- node-version: '24'
24
- - run: yarn install --frozen-lockfile
25
- - run: yarn test:ci
26
- - run: yarn build
27
- - run: npx semantic-release
28
- env:
29
- GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
30
- - uses: codecov/codecov-action@v5
31
- with:
32
- files: coverage/lcov.info
package/.husky/commit-msg DELETED
@@ -1 +0,0 @@
1
- npx --no -- commitlint --edit "$1"
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- yarn test:ci && yarn prettier
package/.prettierignore DELETED
@@ -1,3 +0,0 @@
1
- dist/
2
- node_modules/
3
- coverage/
package/.prettierrc DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "printWidth": 120,
3
- "useTabs": true,
4
- "tabWidth": 4,
5
- "singleQuote": true,
6
- "semi": false,
7
- "trailingComma": "es5",
8
- "bracketSpacing": true,
9
- "overrides": [
10
- {
11
- "files": "./**/*.js",
12
- "options": {
13
- "parser": "babel"
14
- }
15
- },
16
- {
17
- "files": "./**/*.json",
18
- "options": {
19
- "parser": "json"
20
- }
21
- },
22
- {
23
- "files": ".prettierrc",
24
- "options": {
25
- "parser": "json"
26
- }
27
- }
28
- ]
29
- }
package/CLAUDE.md DELETED
@@ -1,59 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Commands
6
-
7
- ```bash
8
- yarn test # watch mode (Vitest)
9
- yarn test:ci # CI mode with coverage (also runs in pre-commit hook)
10
- yarn build # build CJS + ES + UMD to dist/ (Vite library mode)
11
- yarn dev # dev server at http://localhost:10001/ (separate dev/ package)
12
- yarn prettier # format all JS files and stage tracked changes
13
- ```
14
-
15
- Run a single test file:
16
- ```bash
17
- yarn vitest src/hooks/__tests__/useVocal.test.js
18
- ```
19
-
20
- Build formats defined in `vite.config.js` `build.lib`: `cjs` → `dist/index.js`, `es` → `dist/index.es.js`, `umd` → `dist/index.umd.js`.
21
-
22
- ## Architecture
23
-
24
- React library wrapping the [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API) via `@untemps/vocal` (the `SpeechRecognitionWrapper` class).
25
-
26
- ### Public API (`src/index.js`)
27
-
28
- - **`Vocal`** (default export) — the component
29
- - **`useVocal`** — named export, the hook
30
- - **`isSupported`** — boolean re-exported from `@untemps/vocal`
31
-
32
- ### Hook layer (`src/hooks/`)
33
-
34
- | Hook | Role |
35
- |------|------|
36
- | `useVocal` | Creates/manages a `SpeechRecognitionWrapper` instance in a ref. Returns `[ref, { start, stop, abort, subscribe, unsubscribe, clean }]`. Instance is re-created when `lang` or `grammars` change. |
37
- | `useCommands` | Fuzzy-matches a speech result string against a `commands` map using **fuse.js** (default score threshold `0.4` — lower = stricter). Keys are lowercased. |
38
- | `useTimeout` | Manages the recognition timeout: starts on `start` event, pauses on `speechstart`, restarts on `speechend`, fires `_onEnd` on expiry. |
39
-
40
- ### Component (`src/components/Vocal.jsx`)
41
-
42
- Composes the three hooks above. Three render modes depending on `children`:
43
- - **function** `(start, stop, isStarted) => element` — full control
44
- - **React element** — receives `onClick` injected via `cloneElement`
45
- - **no children** — renders the default `<Icon>` button
46
-
47
- All props have default values in the function signature (React 19: `defaultProps` no longer applied to function components). No `propTypes` — removed as deprecated in React 19.
48
-
49
- The `__rsInstance` prop (undocumented) injects a custom `SpeechRecognitionWrapper` instance, used exclusively in tests.
50
-
51
- ### Testing
52
-
53
- `vitest.setup.js` globally mocks `SpeechRecognition`, `Permissions`, `MediaDevices`, and `SpeechGrammarList`. The mock exposes a custom `say(sentence)` method that fires the full `speechstart → result/nomatch → speechend` event sequence synchronously — use it to simulate recognition in tests.
54
-
55
- Vitest globals are enabled (`globals: true`) — `describe`, `it`, `expect`, `vi` available without imports in test files.
56
-
57
- ## Commit convention
58
-
59
- Angular Conventional Commits (`feat`, `fix`, `chore`, `docs`, etc.). Enforced by commitlint on `commit-msg` hook.
Binary file
Binary file
Binary file
Binary file
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- extends: ['@commitlint/config-conventional'],
3
- rules: {
4
- 'subject-case': [2, 'always', ['sentence-case']],
5
- 'scope-case': [2, 'always', ['lower-case', 'upper-case']]
6
- },
7
- }
package/dev/index.html DELETED
@@ -1,24 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <meta name="theme-color" content="#000000" />
7
- <meta name="description" content="react-vocal" />
8
- <title>react-vocal</title>
9
- <style>
10
- * {
11
- font-family: Arial, sans-serif;
12
- font-size: 12px;
13
- }
14
- body {
15
- padding: 32px;
16
- }
17
- </style>
18
- </head>
19
- <body>
20
- <noscript>You need to enable JavaScript to run this app.</noscript>
21
- <div id="root"></div>
22
- <script type="module" src="/src/index.jsx"></script>
23
- </body>
24
- </html>
package/dev/package.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "name": "react-vocal-demo",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "vite",
7
- "build": "vite build",
8
- "preview": "vite preview"
9
- },
10
- "dependencies": {
11
- "react": "^19.2.5",
12
- "react-dom": "^19.2.5"
13
- },
14
- "devDependencies": {
15
- "@vitejs/plugin-react": "^6.0.1",
16
- "vite": "^8.0.10"
17
- }
18
- }
@@ -1,24 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <meta name="theme-color" content="#000000" />
7
- <meta name="description" content="Web site created using create-react-app" />
8
- <title>react-vocal</title>
9
- <script src="./index.js" type="module"></script>
10
- <style>
11
- * {
12
- font-family: Arial,sans-serif;
13
- font-size: 12px;
14
- }
15
- body {
16
- padding: 32px;
17
- }
18
- </style>
19
- </head>
20
- <body>
21
- <noscript>You need to enable JavaScript to run this app.</noscript>
22
- <div id="root"></div>
23
- </body>
24
- </html>
package/dev/src/index.jsx DELETED
@@ -1,66 +0,0 @@
1
- import React, { useMemo, useState } from 'react'
2
- import { createRoot } from 'react-dom/client'
3
-
4
- import Vocal from '../../src'
5
-
6
- const COMMANDS = {
7
- rouge: 'red',
8
- bleu: 'blue',
9
- vert: 'green',
10
- jaune: 'yellow',
11
- }
12
-
13
- const App = () => {
14
- const [logs, setLogs] = useState('')
15
- const [borderColor, setBorderColor] = useState()
16
- const [continuous, setContinuous] = useState(false)
17
-
18
- const _log = (value) => setLogs((prev) => `${prev}${prev.length > 0 ? '\n' : ''} ----- ${value}`)
19
-
20
- // Memoized to avoid recreating the commands object (and re-indexing useCommands) on every render
21
- const commands = useMemo(
22
- () =>
23
- Object.fromEntries(
24
- Object.entries(COMMANDS).map(([key, color]) => [
25
- key,
26
- (rawInput, commandKey) => {
27
- _log(`command matched: "${commandKey}" → ${color}`)
28
- setBorderColor(color)
29
- },
30
- ])
31
- ),
32
- // eslint-disable-next-line react-hooks/exhaustive-deps
33
- []
34
- )
35
-
36
- return (
37
- <>
38
- <Vocal
39
- lang="fr"
40
- commands={commands}
41
- continuous={continuous}
42
- onStart={() => _log('start')}
43
- onEnd={() => _log('end')}
44
- onResult={(result) => _log(`transcript: "${result}"`)}
45
- onError={(e) => _log(`error: ${e.message}`)}
46
- maxAlternatives={3}
47
- />
48
- <p style={{ fontSize: 12, color: '#666', margin: '8px 0' }}>
49
- <label style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
50
- <input type="checkbox" checked={continuous} onChange={(e) => setContinuous(e.target.checked)} />
51
- Mode continu
52
- </label>
53
- </p>
54
- <p style={{ fontSize: 12, color: '#666', margin: '8px 0' }}>
55
- Commandes :{' '}
56
- {Object.keys(COMMANDS).map((k, i) => (
57
- <span key={k}>{i > 0 && ', '}<code>{k}</code></span>
58
- ))}
59
- {' '}— ou dans une phrase (ex : «&nbsp;je veux du vert&nbsp;»)
60
- </p>
61
- <textarea value={logs} rows={30} disabled style={{ width: '100%', borderColor }} />
62
- </>
63
- )
64
- }
65
-
66
- createRoot(document.getElementById('root')).render(<App />)
@@ -1,10 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
-
4
- export default defineConfig({
5
- plugins: [react()],
6
- server: {
7
- port: 10001,
8
- open: true,
9
- },
10
- })