diff --git a/packages/react/dist/index.cjs.js b/packages/react/dist/index.cjs.js index 1fa2a1109..1d8454391 100644 --- a/packages/react/dist/index.cjs.js +++ b/packages/react/dist/index.cjs.js @@ -1,3 +1,3 @@ -"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var o=require("react"),oe=require("react-codemirror6"),R=require("@codemirror/view"),I=require("@codemirror/state"),ae=require("@codemirror/lang-javascript"),s=require("@codemirror/highlight"),re=require("react-hook-inview"),ne=require("@strudel.cycles/eval"),se=require("@strudel.cycles/core/util.mjs"),b=require("@strudel.cycles/tone"),z=require("@strudel.cycles/core"),h=require("@strudel.cycles/midi");function ce(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var f=ce(o);const le="#abb2bf",ie="#7d8799",ue="#ffffff",de="#21252b",W="rgba(0, 0, 0, 0.5)",fe="transparent",P="#353a42",ge="rgba(128, 203, 196, 0.5)",F="#ffcc00",me=R.EditorView.theme({"&":{color:"#ffffff",backgroundColor:fe,fontSize:"15px","z-index":11},".cm-content":{caretColor:F,lineHeight:"22px"},".cm-line":{background:"#2C323699"},"&.cm-focused .cm-cursor":{backgroundColor:F,width:"3px"},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:ge},".cm-panels":{backgroundColor:de,color:"#ffffff"},".cm-panels.cm-panels-top":{borderBottom:"2px solid black"},".cm-panels.cm-panels-bottom":{borderTop:"2px solid black"},".cm-searchMatch":{backgroundColor:"#72a1ff59",outline:"1px solid #457dff"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"#6199ff2f"},".cm-activeLine":{backgroundColor:W},".cm-selectionMatch":{backgroundColor:"#aafe661a"},"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bad0f847",outline:"1px solid #515a6b"},".cm-gutters":{background:"transparent",color:"#676e95",border:"none"},".cm-activeLineGutter":{backgroundColor:W},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none",color:"#ddd"},".cm-tooltip":{border:"none",backgroundColor:P},".cm-tooltip .cm-tooltip-arrow:before":{borderTopColor:"transparent",borderBottomColor:"transparent"},".cm-tooltip .cm-tooltip-arrow:after":{borderTopColor:P,borderBottomColor:P},".cm-tooltip-autocomplete":{"& > ul > li[aria-selected]":{backgroundColor:W,color:le}}},{dark:!0}),be=s.HighlightStyle.define([{tag:s.tags.keyword,color:"#c792ea"},{tag:s.tags.operator,color:"#89ddff"},{tag:s.tags.special(s.tags.variableName),color:"#eeffff"},{tag:s.tags.typeName,color:"#f07178"},{tag:s.tags.atom,color:"#f78c6c"},{tag:s.tags.number,color:"#ff5370"},{tag:s.tags.definition(s.tags.variableName),color:"#82aaff"},{tag:s.tags.string,color:"#c3e88d"},{tag:s.tags.special(s.tags.string),color:"#f07178"},{tag:s.tags.comment,color:ie},{tag:s.tags.variableName,color:"#f07178"},{tag:s.tags.tagName,color:"#ff5370"},{tag:s.tags.bracket,color:"#a2a1a4"},{tag:s.tags.meta,color:"#ffcb6b"},{tag:s.tags.attributeName,color:"#c792ea"},{tag:s.tags.propertyName,color:"#c792ea"},{tag:s.tags.className,color:"#decb6b"},{tag:s.tags.invalid,color:ue}]),pe=[me,be],H=I.StateEffect.define(),he=I.StateField.define({create(){return R.Decoration.none},update(e,r){try{for(let l of r.effects)l.is(H)&&(e=R.Decoration.set(l.value.flatMap(u=>(u.context.locations||[]).map(({start:g,end:c})=>{const i=u.context.color||"#FFCA28";let m=r.newDoc.line(g.line).from+g.column,n=r.newDoc.line(c.line).from+c.column;const a=r.newDoc.length;return m>a||n>a?void 0:R.Decoration.mark({attributes:{style:`outline: 1px solid ${i}`}}).range(m,n)})).filter(Boolean),!0));return e}catch{return e}},provide:e=>R.EditorView.decorations.from(e)});function $({value:e,onChange:r,onViewChanged:l,onCursor:u,options:g,editorDidMount:c,theme:i}){return f.default.createElement(f.default.Fragment,null,f.default.createElement(oe.CodeMirror,{onViewChange:l,style:{display:"flex",flexDirection:"column",flex:"1 0 auto"},value:e,onChange:r,extensions:[ae.javascript(),i||pe,he]}))}function Q(e){const{onEvent:r,onQuery:l,onSchedule:u,ready:g=!0,onDraw:c}=e,[i,m]=o.useState(!1),n=1,a=()=>Math.floor(b.Tone.getTransport().seconds/n),C=(v=a())=>{const y=new z.TimeSpan(v,v+1),x=l?.(new z.State(y))||[];u?.(x,v);const D=y.begin.valueOf();b.Tone.getTransport().cancel(D);const N=(v+1)*n-.5,B=Math.max(b.Tone.getTransport().seconds,N)+.1;b.Tone.getTransport().schedule(()=>{C(v+1)},B),x?.filter(p=>p.part.begin.equals(p.whole?.begin)).forEach(p=>{b.Tone.getTransport().schedule(k=>{r(k,p,b.Tone.getContext().currentTime),b.Tone.Draw.schedule(()=>{c?.(k,p)},k)},p.part.begin.valueOf())})};o.useEffect(()=>{g&&C()},[r,u,l,c,g]);const S=async()=>{m(!0),await b.Tone.start(),b.Tone.getTransport().start("+0.1")},w=()=>{b.Tone.getTransport().pause(),m(!1)};return{start:S,stop:w,onEvent:r,started:i,setStarted:m,toggle:()=>i?w():S(),query:C,activeCycle:a}}function U(e){return o.useEffect(()=>(window.addEventListener("message",e),()=>window.removeEventListener("message",e)),[e]),o.useCallback(r=>window.postMessage(r,"*"),[])}let ve=()=>Math.floor((1+Math.random())*65536).toString(16).substring(1);const ye=e=>encodeURIComponent(btoa(e));function G({tune:e,defaultSynth:r,autolink:l=!0,onEvent:u,onDraw:g}){const c=o.useMemo(()=>ve(),[]),[i,m]=o.useState(e),[n,a]=o.useState(),[C,S]=o.useState(""),[w,T]=o.useState(),[v,y]=o.useState(!1),[x,D]=o.useState(""),[N,B]=o.useState(),p=o.useMemo(()=>i!==n||w,[i,n,w]),k=o.useCallback(d=>S(t=>t+`${t?` +"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var t=require("react"),ae=require("react-codemirror6"),H=require("@codemirror/view"),$=require("@codemirror/state"),re=require("@codemirror/lang-javascript"),n=require("@codemirror/highlight"),ne=require("react-hook-inview"),se=require("@strudel.cycles/eval"),ce=require("@strudel.cycles/core/util.mjs"),b=require("@strudel.cycles/tone"),z=require("@strudel.cycles/core"),h=require("@strudel.cycles/midi");function le(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var g=le(t);const ie="#abb2bf",ue="#7d8799",de="#ffffff",fe="#21252b",V="rgba(0, 0, 0, 0.5)",ge="transparent",A="#353a42",me="rgba(128, 203, 196, 0.5)",F="#ffcc00",be=H.EditorView.theme({"&":{color:"#ffffff",backgroundColor:ge,fontSize:"15px","z-index":11},".cm-content":{caretColor:F,lineHeight:"22px"},".cm-line":{background:"#2C323699"},"&.cm-focused .cm-cursor":{backgroundColor:F,width:"3px"},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:me},".cm-panels":{backgroundColor:fe,color:"#ffffff"},".cm-panels.cm-panels-top":{borderBottom:"2px solid black"},".cm-panels.cm-panels-bottom":{borderTop:"2px solid black"},".cm-searchMatch":{backgroundColor:"#72a1ff59",outline:"1px solid #457dff"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"#6199ff2f"},".cm-activeLine":{backgroundColor:V},".cm-selectionMatch":{backgroundColor:"#aafe661a"},"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bad0f847",outline:"1px solid #515a6b"},".cm-gutters":{background:"transparent",color:"#676e95",border:"none"},".cm-activeLineGutter":{backgroundColor:V},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none",color:"#ddd"},".cm-tooltip":{border:"none",backgroundColor:A},".cm-tooltip .cm-tooltip-arrow:before":{borderTopColor:"transparent",borderBottomColor:"transparent"},".cm-tooltip .cm-tooltip-arrow:after":{borderTopColor:A,borderBottomColor:A},".cm-tooltip-autocomplete":{"& > ul > li[aria-selected]":{backgroundColor:V,color:ie}}},{dark:!0}),pe=n.HighlightStyle.define([{tag:n.tags.keyword,color:"#c792ea"},{tag:n.tags.operator,color:"#89ddff"},{tag:n.tags.special(n.tags.variableName),color:"#eeffff"},{tag:n.tags.typeName,color:"#f07178"},{tag:n.tags.atom,color:"#f78c6c"},{tag:n.tags.number,color:"#ff5370"},{tag:n.tags.definition(n.tags.variableName),color:"#82aaff"},{tag:n.tags.string,color:"#c3e88d"},{tag:n.tags.special(n.tags.string),color:"#f07178"},{tag:n.tags.comment,color:ue},{tag:n.tags.variableName,color:"#f07178"},{tag:n.tags.tagName,color:"#ff5370"},{tag:n.tags.bracket,color:"#a2a1a4"},{tag:n.tags.meta,color:"#ffcb6b"},{tag:n.tags.attributeName,color:"#c792ea"},{tag:n.tags.propertyName,color:"#c792ea"},{tag:n.tags.className,color:"#decb6b"},{tag:n.tags.invalid,color:de}]),he=[be,pe],W=$.StateEffect.define(),ve=$.StateField.define({create(){return H.Decoration.none},update(e,a){try{for(let i of a.effects)i.is(W)&&(e=H.Decoration.set(i.value.flatMap(u=>(u.context.locations||[]).map(({start:d,end:s})=>{const c=u.context.color||"#FFCA28";let m=a.newDoc.line(d.line).from+d.column,l=a.newDoc.line(s.line).from+s.column;const r=a.newDoc.length;return m>r||l>r?void 0:H.Decoration.mark({attributes:{style:`outline: 1px solid ${c}`}}).range(m,l)})).filter(Boolean),!0));return e}catch{return e}},provide:e=>H.EditorView.decorations.from(e)});function Q({value:e,onChange:a,onViewChanged:i,onCursor:u,options:d,editorDidMount:s,theme:c}){return g.default.createElement(g.default.Fragment,null,g.default.createElement(ae.CodeMirror,{onViewChange:i,style:{display:"flex",flexDirection:"column",flex:"1 0 auto"},value:e,onChange:a,extensions:[re.javascript(),c||he,ve]}))}function U(e){const{onEvent:a,onQuery:i,onSchedule:u,ready:d=!0,onDraw:s}=e,[c,m]=t.useState(!1),l=1,r=()=>Math.floor(b.Tone.getTransport().seconds/l),v=(y=r())=>{const S=new z.TimeSpan(y,y+1),D=i?.(new z.State(S))||[];u?.(D,y);const N=S.begin.valueOf();b.Tone.getTransport().cancel(N);const C=(y+1)*l-.5,R=Math.max(b.Tone.getTransport().seconds,C)+.1;b.Tone.getTransport().schedule(()=>{v(y+1)},R),D?.filter(p=>p.part.begin.equals(p.whole?.begin)).forEach(p=>{b.Tone.getTransport().schedule(M=>{a(M,p,b.Tone.getContext().currentTime),b.Tone.Draw.schedule(()=>{s?.(M,p)},M)},p.part.begin.valueOf())})};t.useEffect(()=>{d&&v()},[a,u,i,s,d]);const w=async()=>{m(!0),await b.Tone.start(),b.Tone.getTransport().start("+0.1")},k=()=>{b.Tone.getTransport().pause(),m(!1)};return{start:w,stop:k,onEvent:a,started:c,setStarted:m,toggle:()=>c?k():w(),query:v,activeCycle:r}}function G(e){return t.useEffect(()=>(window.addEventListener("message",e),()=>window.removeEventListener("message",e)),[e]),t.useCallback(a=>window.postMessage(a,"*"),[])}let ye=()=>Math.floor((1+Math.random())*65536).toString(16).substring(1);const Ce=e=>encodeURIComponent(btoa(e));function J({tune:e,defaultSynth:a,autolink:i=!0,onEvent:u,onDraw:d}){const s=t.useMemo(()=>ye(),[]),[c,m]=t.useState(e),[l,r]=t.useState(),[v,w]=t.useState(""),[k,_]=t.useState(),[y,S]=t.useState(!1),[D,N]=t.useState(""),[C,R]=t.useState(),p=t.useMemo(()=>c!==l||k,[c,l,k]),M=t.useCallback(f=>w(o=>o+`${o?` -`:""}${d}`),[]),K=o.useMemo(()=>{if(n&&!n.includes("strudel disable-highlighting"))return(d,t)=>g?.(d,t,n)},[n,g]),M=Q({onDraw:K,onEvent:o.useCallback((d,t,Z)=>{try{u?.(t),t.context.logs?.length&&t.context.logs.forEach(k);const{onTrigger:_,velocity:ee}=t.context;if(_)_(d,t,Z,1,t.wholeOrPart().begin.valueOf(),t.duration.valueOf());else if(r){const te=se.getPlayableNoteValue(t);r.triggerAttackRelease(te,t.duration.valueOf(),d,ee)}else throw new Error("no defaultSynth passed to useRepl.")}catch(_){console.warn(_),_.message="unplayable event: "+_?.message,k(_.message)}},[u,k,r]),onQuery:o.useCallback(d=>{try{return N?.query(d)||[]}catch(t){return console.warn(t),t.message="query error: "+t.message,T(t),[]}},[N]),onSchedule:o.useCallback((d,t)=>X(d,t),[]),ready:!!N&&!!n}),A=U(({data:{from:d,type:t}})=>{t==="start"&&d!==c&&(M.setStarted(!1),a(void 0))}),L=o.useCallback(async(d=i)=>{if(n&&!p){T(void 0),M.start();return}try{y(!0);const t=await ne.evaluate(d);M.start(),A({type:"start",from:c}),B(()=>t.pattern),l&&(window.location.hash="#"+encodeURIComponent(btoa(i))),D(ye(i)),T(void 0),a(d),y(!1)}catch(t){t.message="evaluation error: "+t.message,console.warn(t),T(t)}},[n,p,i,M,l,c,A]),X=(d,t)=>{d.length},Y=()=>{M.started?M.stop():L()};return o.useEffect(()=>()=>M.stop(),[]),{pending:v,code:i,setCode:m,pattern:N,error:w,cycle:M,setPattern:B,dirty:p,log:C,togglePlay:Y,setActiveCode:a,activateCode:L,activeCode:n,pushLog:k,hash:x}}function V(...e){return e.filter(Boolean).join(" ")}let q=[],O;function J({view:e,pattern:r,active:l}){o.useEffect(()=>{if(e)if(r&&l){let g=function(){try{const c=b.Tone.getTransport().seconds,m=[Math.max(O||c,c-1/10),c+1/60];O=c+1/60,q=q.filter(a=>a.whole.end>c);const n=r.queryArc(...m).filter(a=>a.hasOnset());q=q.concat(n),e.dispatch({effects:H.of(q)})}catch{e.dispatch({effects:H.of([])})}u=requestAnimationFrame(g)},u=requestAnimationFrame(g);return()=>{cancelAnimationFrame(u)}}else q=[],e.dispatch({effects:H.of([])})},[r,l,e])}const Ce="_container_10e1g_1",we="_header_10e1g_5",ke="_buttons_10e1g_9",Me="_button_10e1g_9",Ee="_buttonDisabled_10e1g_17",Te="_error_10e1g_21",xe="_body_10e1g_25";var E={container:Ce,header:we,buttons:ke,button:Me,buttonDisabled:Ee,error:Te,body:xe};function j({type:e}){return f.default.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",className:"sc-h-5 sc-w-5",viewBox:"0 0 20 20",fill:"currentColor"},{refresh:f.default.createElement("path",{fillRule:"evenodd",d:"M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z",clipRule:"evenodd"}),play:f.default.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z",clipRule:"evenodd"}),pause:f.default.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z",clipRule:"evenodd"})}[e])}function _e({tune:e,defaultSynth:r,hideOutsideView:l=!1,theme:u}){const{code:g,setCode:c,pattern:i,activateCode:m,error:n,cycle:a,dirty:C,togglePlay:S}=G({tune:e,defaultSynth:r,autolink:!1}),[w,T]=o.useState(),[v,y]=re.useInView({threshold:.01}),x=o.useRef(),D=o.useMemo(()=>((y||!l)&&(x.current=!0),y||x.current),[y,l]);return J({view:w,pattern:i,active:a.started}),f.default.createElement("div",{className:E.container,ref:v},f.default.createElement("div",{className:E.header},f.default.createElement("div",{className:E.buttons},f.default.createElement("button",{className:V(E.button,a.started?"sc-animate-pulse":""),onClick:()=>S()},f.default.createElement(j,{type:a.started?"pause":"play"})),f.default.createElement("button",{className:V(C?E.button:E.buttonDisabled),onClick:()=>m()},f.default.createElement(j,{type:"refresh"}))),n&&f.default.createElement("div",{className:E.error},n.message)),f.default.createElement("div",{className:E.body},D&&f.default.createElement($,{theme:u,value:g,onChange:c,onViewChanged:T})))}function Se(e){const{ready:r,connected:l,disconnected:u}=e,[g,c]=o.useState(!0),[i,m]=o.useState(h.WebMidi?.outputs||[]);return o.useEffect(()=>{h.enableWebMidi().then(()=>{h.WebMidi.addListener("connected",a=>{m([...h.WebMidi.outputs]),l?.(h.WebMidi,a)}),h.WebMidi.addListener("disconnected",a=>{m([...h.WebMidi.outputs]),u?.(h.WebMidi,a)}),r?.(h.WebMidi),c(!1)}).catch(a=>{if(a){console.error(a),console.warn("Web Midi could not be enabled..");return}})},[r,l,u,i]),{loading:g,outputs:i,outputByName:a=>h.WebMidi.getOutputByName(a)}}exports.CodeMirror=$;exports.MiniRepl=_e;exports.cx=V;exports.useCycle=Q;exports.useHighlighting=J;exports.usePostMessage=U;exports.useRepl=G;exports.useWebMidi=Se; +`:""}${f}`),[]),X=t.useMemo(()=>{if(l&&!l.includes("strudel disable-highlighting"))return(f,o)=>d?.(f,o,l)},[l,d]),E=U({onDraw:X,onEvent:t.useCallback((f,o,T)=>{try{u?.(o),o.context.logs?.length&&o.context.logs.forEach(M);const{onTrigger:q,velocity:te}=o.context;if(q)q(f,o,T,1,o.wholeOrPart().begin.valueOf(),o.duration.valueOf());else if(a){const oe=ce.getPlayableNoteValue(o);a.triggerAttackRelease(oe,o.duration.valueOf(),f,te)}else throw new Error("no defaultSynth passed to useRepl.")}catch(q){console.warn(q),q.message="unplayable event: "+q?.message,M(q.message)}},[u,M,a]),onQuery:t.useCallback(f=>{try{return C?.query(f)||[]}catch(o){return console.warn(o),o.message="query error: "+o.message,_(o),[]}},[C]),onSchedule:t.useCallback((f,o)=>Y(f,o),[]),ready:!!C&&!!l}),O=G(({data:{from:f,type:o}})=>{o==="start"&&f!==s&&(E.setStarted(!1),r(void 0))}),P=t.useCallback(async(f=c,o=!1)=>{if(l&&!p){_(void 0),!o&&E.start();return}try{S(!0);const T=await se.evaluate(f);!o&&E.start(),O({type:"start",from:s}),R(()=>T.pattern),i&&(window.location.hash="#"+encodeURIComponent(btoa(c))),N(Ce(c)),_(void 0),r(f),S(!1)}catch(T){T.message="evaluation error: "+T.message,console.warn(T),_(T)}},[l,p,c,E,i,s,O]),Y=(f,o)=>{f.length},Z=()=>{E.started?E.stop():P()},ee=()=>{P(c,!0)};return t.useEffect(()=>()=>E.stop(),[]),{pending:y,code:c,setCode:m,pattern:C,error:k,cycle:E,setPattern:R,dirty:p,log:v,togglePlay:Z,setActiveCode:r,activateCode:P,evaluateOnly:ee,activeCode:l,pushLog:M,hash:D}}function L(...e){return e.filter(Boolean).join(" ")}let B=[],j;function K({view:e,pattern:a,active:i}){t.useEffect(()=>{if(e)if(a&&i){let d=function(){try{const s=b.Tone.getTransport().seconds,m=[Math.max(j||s,s-1/10),s+1/60];j=s+1/60,B=B.filter(r=>r.whole.end>s);const l=a.queryArc(...m).filter(r=>r.hasOnset());B=B.concat(l),e.dispatch({effects:W.of(B)})}catch{e.dispatch({effects:W.of([])})}u=requestAnimationFrame(d)},u=requestAnimationFrame(d);return()=>{cancelAnimationFrame(u)}}else B=[],e.dispatch({effects:W.of([])})},[a,i,e])}const we="_container_10e1g_1",ke="_header_10e1g_5",Me="_buttons_10e1g_9",Ee="_button_10e1g_9",Te="_buttonDisabled_10e1g_17",xe="_error_10e1g_21",_e="_body_10e1g_25";var x={container:we,header:ke,buttons:Me,button:Ee,buttonDisabled:Te,error:xe,body:_e};function I({type:e}){return g.default.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",className:"sc-h-5 sc-w-5",viewBox:"0 0 20 20",fill:"currentColor"},{refresh:g.default.createElement("path",{fillRule:"evenodd",d:"M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z",clipRule:"evenodd"}),play:g.default.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z",clipRule:"evenodd"}),pause:g.default.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z",clipRule:"evenodd"})}[e])}function Se({tune:e,defaultSynth:a,hideOutsideView:i=!1,theme:u,init:d}){const{code:s,setCode:c,pattern:m,activateCode:l,evaluateOnly:r,error:v,cycle:w,dirty:k,togglePlay:_}=J({tune:e,defaultSynth:a,autolink:!1});t.useEffect(()=>{d&&r()},[e,d]);const[y,S]=t.useState(),[D,N]=ne.useInView({threshold:.01}),C=t.useRef(),R=t.useMemo(()=>((N||!i)&&(C.current=!0),N||C.current),[N,i]);return K({view:y,pattern:m,active:w.started}),g.default.createElement("div",{className:x.container,ref:D},g.default.createElement("div",{className:x.header},g.default.createElement("div",{className:x.buttons},g.default.createElement("button",{className:L(x.button,w.started?"sc-animate-pulse":""),onClick:()=>_()},g.default.createElement(I,{type:w.started?"pause":"play"})),g.default.createElement("button",{className:L(k?x.button:x.buttonDisabled),onClick:()=>l()},g.default.createElement(I,{type:"refresh"}))),v&&g.default.createElement("div",{className:x.error},v.message)),g.default.createElement("div",{className:x.body},R&&g.default.createElement(Q,{theme:u,value:s,onChange:c,onViewChanged:S})))}function Ne(e){const{ready:a,connected:i,disconnected:u}=e,[d,s]=t.useState(!0),[c,m]=t.useState(h.WebMidi?.outputs||[]);return t.useEffect(()=>{h.enableWebMidi().then(()=>{h.WebMidi.addListener("connected",r=>{m([...h.WebMidi.outputs]),i?.(h.WebMidi,r)}),h.WebMidi.addListener("disconnected",r=>{m([...h.WebMidi.outputs]),u?.(h.WebMidi,r)}),a?.(h.WebMidi),s(!1)}).catch(r=>{if(r){console.error(r),console.warn("Web Midi could not be enabled..");return}})},[a,i,u,c]),{loading:d,outputs:c,outputByName:r=>h.WebMidi.getOutputByName(r)}}exports.CodeMirror=Q;exports.MiniRepl=Se;exports.cx=L;exports.useCycle=U;exports.useHighlighting=K;exports.usePostMessage=G;exports.useRepl=J;exports.useWebMidi=Ne; diff --git a/packages/react/dist/index.es.js b/packages/react/dist/index.es.js index 3f3b67a50..ccee46d9a 100644 --- a/packages/react/dist/index.es.js +++ b/packages/react/dist/index.es.js @@ -383,16 +383,16 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP }); const activateCode = useCallback( - async (_code = code) => { + async (_code = code, evaluateOnly = false) => { if (activeCode && !dirty) { setError(undefined); - cycle.start(); + !evaluateOnly && cycle.start(); return; } try { setPending(true); const parsed = await evaluate(_code); - cycle.start(); + !evaluateOnly && cycle.start(); broadcast({ type: 'start', from: id }); setPattern(() => parsed.pattern); if (autolink) { @@ -423,6 +423,10 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP } }; + const evaluateOnly = () => { + activateCode(code, true); + }; + useEffect(() => { return () => cycle.stop(); }, []); @@ -440,6 +444,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP togglePlay, setActiveCode, activateCode, + evaluateOnly, activeCode, pushLog, hash, @@ -542,12 +547,15 @@ function Icon({ type }) { }[type]); } -function MiniRepl({ tune, defaultSynth, hideOutsideView = false, theme }) { - const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({ +function MiniRepl({ tune, defaultSynth, hideOutsideView = false, theme, init }) { + const { code, setCode, pattern, activateCode, evaluateOnly, error, cycle, dirty, togglePlay } = useRepl({ tune, defaultSynth, autolink: false }); + useEffect(() => { + init && evaluateOnly(); + }, [tune, init]); const [view, setView] = useState(); const [ref, isVisible] = useInView({ threshold: 0.01 diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index 3f296f8fe..ce2f484bf 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo, useRef } from 'react'; +import React, { useState, useMemo, useRef, useEffect } from 'react'; import { useInView } from 'react-hook-inview'; import useRepl from '../hooks/useRepl.mjs'; import cx from '../cx'; @@ -9,12 +9,15 @@ import './style.css'; import styles from './MiniRepl.module.css'; import { Icon } from './Icon'; -export function MiniRepl({ tune, defaultSynth, hideOutsideView = false, theme }) { - const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({ +export function MiniRepl({ tune, defaultSynth, hideOutsideView = false, theme, init }) { + const { code, setCode, pattern, activateCode, evaluateOnly, error, cycle, dirty, togglePlay } = useRepl({ tune, defaultSynth, autolink: false, }); + useEffect(() => { + init && evaluateOnly(); + }, [tune, init]); const [view, setView] = useState(); const [ref, isVisible] = useInView({ threshold: 0.01, diff --git a/packages/react/src/hooks/useRepl.mjs b/packages/react/src/hooks/useRepl.mjs index e225b0338..a7c9cbe37 100644 --- a/packages/react/src/hooks/useRepl.mjs +++ b/packages/react/src/hooks/useRepl.mjs @@ -100,16 +100,16 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP }); const activateCode = useCallback( - async (_code = code) => { + async (_code = code, evaluateOnly = false) => { if (activeCode && !dirty) { setError(undefined); - cycle.start(); + !evaluateOnly && cycle.start(); return; } try { setPending(true); const parsed = await evaluate(_code); - cycle.start(); + !evaluateOnly && cycle.start(); broadcast({ type: 'start', from: id }); setPattern(() => parsed.pattern); if (autolink) { @@ -142,6 +142,10 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP } }; + const evaluateOnly = () => { + activateCode(code, true); + }; + useEffect(() => { return () => cycle.stop(); }, []); @@ -159,6 +163,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP togglePlay, setActiveCode, activateCode, + evaluateOnly, activeCode, pushLog, hash,