@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.
- package/CHANGELOG.md +24 -0
- package/README.md +23 -5
- package/dist/index.es.js +233 -759
- package/dist/index.js +2 -4
- package/package.json +7 -6
- package/.github/workflows/publish.yml +0 -32
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -1
- package/.prettierignore +0 -3
- package/.prettierrc +0 -29
- package/CLAUDE.md +0 -59
- package/assets/icon-idle.png +0 -0
- package/assets/icon-listening.png +0 -0
- package/assets/microphone.png +0 -0
- package/assets/react-vocal.png +0 -0
- package/commitlint.config.js +0 -7
- package/dev/index.html +0 -24
- package/dev/package.json +0 -18
- package/dev/public/index.html +0 -24
- package/dev/src/index.jsx +0 -66
- package/dev/vite.config.js +0 -10
- package/dev/yarn.lock +0 -325
- package/dist/index.es.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.umd.js +0 -9
- package/dist/index.umd.js.map +0 -1
- package/src/components/Icon.jsx +0 -24
- package/src/components/Vocal.jsx +0 -261
- package/src/components/__tests__/Icon.test.jsx +0 -38
- package/src/components/__tests__/Vocal.test.jsx +0 -748
- package/src/components/__tests__/VocalWithMockedUseVocal.test.jsx +0 -38
- package/src/components/__tests__/__snapshots__/Icon.test.jsx.snap +0 -21
- package/src/components/__tests__/__snapshots__/Vocal.test.jsx.snap +0 -28
- package/src/hooks/__tests__/useCommands.test.js +0 -115
- package/src/hooks/__tests__/useTimeout.test.js +0 -69
- package/src/hooks/__tests__/useVocal.test.js +0 -207
- package/src/hooks/useCommands.js +0 -75
- package/src/hooks/useTimeout.js +0 -21
- package/src/hooks/useVocal.js +0 -56
- package/src/index.js +0 -7
- package/vite.config.js +0 -36
- 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)}})()})),
|
|
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.
|
|
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": "^
|
|
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
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.
|
package/assets/icon-idle.png
DELETED
|
Binary file
|
|
Binary file
|
package/assets/microphone.png
DELETED
|
Binary file
|
package/assets/react-vocal.png
DELETED
|
Binary file
|
package/commitlint.config.js
DELETED
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
|
-
}
|
package/dev/public/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="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 : « je veux du vert »)
|
|
60
|
-
</p>
|
|
61
|
-
<textarea value={logs} rows={30} disabled style={{ width: '100%', borderColor }} />
|
|
62
|
-
</>
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
createRoot(document.getElementById('root')).render(<App />)
|