mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-15 15:48:30 +00:00
4 lines
12 KiB
JavaScript
4 lines
12 KiB
JavaScript
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var t=require("react"),Z=require("@uiw/react-codemirror"),S=require("@codemirror/view"),A=require("@codemirror/state"),ee=require("@codemirror/lang-javascript"),p=require("@lezer/highlight"),te=require("@uiw/codemirror-themes"),re=require("react-hook-inview"),B=require("@strudel.cycles/eval"),C=require("@strudel.cycles/tone"),z=require("@strudel.cycles/core"),oe=require("@strudel.cycles/webaudio"),T=require("@strudel.cycles/midi");function j(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var v=j(t),se=j(Z),ae=te.createTheme({theme:"dark",settings:{background:"#222",foreground:"#75baff",caret:"#ffcc00",selection:"rgba(128, 203, 196, 0.5)",selectionMatch:"#036dd626",lineHighlight:"#8a91991a",gutterBackground:"transparent",gutterForeground:"#676e95"},styles:[{tag:p.tags.keyword,color:"#c792ea"},{tag:p.tags.operator,color:"#89ddff"},{tag:p.tags.special(p.tags.variableName),color:"#eeffff"},{tag:p.tags.typeName,color:"#f07178"},{tag:p.tags.atom,color:"#f78c6c"},{tag:p.tags.number,color:"#ff5370"},{tag:p.tags.definition(p.tags.variableName),color:"#82aaff"},{tag:p.tags.string,color:"#c3e88d"},{tag:p.tags.special(p.tags.string),color:"#f07178"},{tag:p.tags.comment,color:"#7d8799"},{tag:p.tags.variableName,color:"#f07178"},{tag:p.tags.tagName,color:"#ff5370"},{tag:p.tags.bracket,color:"#a2a1a4"},{tag:p.tags.meta,color:"#ffcb6b"},{tag:p.tags.attributeName,color:"#c792ea"},{tag:p.tags.propertyName,color:"#c792ea"},{tag:p.tags.className,color:"#decb6b"},{tag:p.tags.invalid,color:"#ffffff"}]});const W=A.StateEffect.define(),ne=A.StateField.define({create(){return S.Decoration.none},update(e,o){try{for(let s of o.effects)if(s.is(W))if(s.value){const a=S.Decoration.mark({attributes:{style:"background-color: #FFCA2880"}});e=S.Decoration.set([a.range(0,o.newDoc.length)])}else e=S.Decoration.set([]);return e}catch(s){return console.warn("flash error",s),e}},provide:e=>S.EditorView.decorations.from(e)}),$=e=>{e.dispatch({effects:W.of(!0)}),setTimeout(()=>{e.dispatch({effects:W.of(!1)})},200)},P=A.StateEffect.define(),ce=A.StateField.define({create(){return S.Decoration.none},update(e,o){try{for(let s of o.effects)if(s.is(P)){const a=s.value.map(n=>(n.context.locations||[]).map(({start:l,end:c})=>{const r=n.context.color||"#FFCA28";let u=o.newDoc.line(l.line).from+l.column,i=o.newDoc.line(c.line).from+c.column;const g=o.newDoc.length;return u>g||i>g?void 0:S.Decoration.mark({attributes:{style:`outline: 1.5px solid ${r};`}}).range(u,i)})).flat().filter(Boolean)||[];e=S.Decoration.set(a,!0)}return e}catch{return S.Decoration.set([])}},provide:e=>S.EditorView.decorations.from(e)}),ie=[ee.javascript(),ae,ce,ne];function K({value:e,onChange:o,onViewChanged:s,onSelectionChange:a,options:n,editorDidMount:l}){const c=t.useCallback(i=>{o?.(i)},[o]),r=t.useCallback(i=>{s?.(i)},[s]),u=t.useCallback(i=>{i.selectionSet&&a&&a?.(i.state.selection)},[a]);return v.default.createElement(v.default.Fragment,null,v.default.createElement(se.default,{value:e,onChange:c,onCreateEditor:r,onUpdate:u,extensions:ie}))}function U(e){const{onEvent:o,onQuery:s,onSchedule:a,ready:n=!0,onDraw:l}=e,[c,r]=t.useState(!1),u=1,i=()=>Math.floor(C.Tone.getTransport().seconds/u),g=(h=i())=>{const M=new z.TimeSpan(h,h+1),w=s?.(new z.State(M))||[];a?.(w,h);const m=M.begin.valueOf();C.Tone.getTransport().cancel(m);const D=(h+1)*u-.5,_=Math.max(C.Tone.getTransport().seconds,D)+.1;C.Tone.getTransport().schedule(()=>{g(h+1)},_),w?.filter(E=>E.part.begin.equals(E.whole?.begin)).forEach(E=>{C.Tone.getTransport().schedule(x=>{o(x,E,C.Tone.getContext().currentTime),C.Tone.Draw.schedule(()=>{l?.(x,E)},x)},E.part.begin.valueOf())})};t.useEffect(()=>{n&&g()},[o,a,s,l,n]);const b=async()=>{r(!0),await C.Tone.start(),C.Tone.getTransport().start("+0.1")},f=()=>{C.Tone.getTransport().pause(),r(!1)};return{start:b,stop:f,onEvent:o,started:c,setStarted:r,toggle:()=>c?f():b(),query:g,activeCycle:i}}function Q(e){return t.useEffect(()=>(window.addEventListener("message",e),()=>window.removeEventListener("message",e)),[e]),t.useCallback(o=>window.postMessage(o,"*"),[])}let le=()=>Math.floor((1+Math.random())*65536).toString(16).substring(1);const ue=e=>encodeURIComponent(btoa(e));function J({tune:e,autolink:o=!0,onEvent:s,onDraw:a}){const n=t.useMemo(()=>le(),[]),[l,c]=t.useState(e),[r,u]=t.useState(),[i,g]=t.useState(""),[b,f]=t.useState(),[k,h]=t.useState(!1),[M,w]=t.useState(""),[m,D]=t.useState(),_=t.useMemo(()=>l!==r||b,[l,r,b]),E=t.useCallback(y=>g(d=>d+`${d?`
|
|
|
|
`:""}${y}`),[]),x=t.useMemo(()=>{if(r&&!r.includes("strudel disable-highlighting"))return(y,d)=>a?.(y,d,r)},[r,a]),L=t.useMemo(()=>r&&r.includes("strudel hide-header"),[r]),q=t.useMemo(()=>r&&r.includes("strudel hide-console"),[r]),R=U({onDraw:x,onEvent:t.useCallback((y,d,Y)=>{try{s?.(d),d.context.logs?.length&&d.context.logs.forEach(E);const{onTrigger:F=oe.webaudioOutputTrigger}=d.context;F(y,d,Y,1)}catch(F){console.warn(F),F.message="unplayable event: "+F?.message,E(F.message)}},[s,E]),onQuery:t.useCallback(y=>{try{return m?.query(y)||[]}catch(d){return console.warn(d),d.message="query error: "+d.message,f(d),[]}},[m]),onSchedule:t.useCallback((y,d)=>X(y),[]),ready:!!m&&!!r}),O=Q(({data:{from:y,type:d}})=>{d==="start"&&y!==n&&(R.setStarted(!1),u(void 0))}),I=t.useCallback(async(y=l)=>{if(r&&!_){f(void 0),R.start();return}try{h(!0);const d=await B.evaluate(y);R.start(),O({type:"start",from:n}),D(()=>d.pattern),o&&(window.location.hash="#"+encodeURIComponent(btoa(l))),w(ue(l)),f(void 0),u(y),h(!1)}catch(d){d.message="evaluation error: "+d.message,console.warn(d),f(d)}},[r,_,l,R,o,n,O]),X=(y,d)=>{y.length};return{hideHeader:L,hideConsole:q,pending:k,code:l,setCode:c,pattern:m,error:b,cycle:R,setPattern:D,dirty:_,log:i,togglePlay:()=>{R.started?R.stop():I()},setActiveCode:u,activateCode:I,activeCode:r,pushLog:E,hash:M}}function H(...e){return e.filter(Boolean).join(" ")}function G({view:e,pattern:o,active:s,getTime:a}){const n=t.useRef([]),l=t.useRef();t.useEffect(()=>{if(e)if(o&&s){let r=function(){try{const u=a(),g=[Math.max(l.current||u,u-1/10),u+1/60];l.current=u+1/60,n.current=n.current.filter(f=>f.whole.end>u);const b=o.queryArc(...g).filter(f=>f.hasOnset());n.current=n.current.concat(b),e.dispatch({effects:P.of(n.current)})}catch{e.dispatch({effects:P.of([])})}c=requestAnimationFrame(r)},c=requestAnimationFrame(r);return()=>{cancelAnimationFrame(c)}}else n.current=[],e.dispatch({effects:P.of([])})},[o,s,e])}const de="_container_3i85k_1",fe="_header_3i85k_5",ge="_buttons_3i85k_9",he="_button_3i85k_9",me="_buttonDisabled_3i85k_17",pe="_error_3i85k_21",be="_body_3i85k_25";var N={container:de,header:fe,buttons:ge,button:he,buttonDisabled:me,error:pe,body:be};function V({type:e}){return v.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:v.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:v.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:v.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 ve({tune:e,hideOutsideView:o=!1,init:s,onEvent:a,enableKeyboard:n}){const{code:l,setCode:c,pattern:r,activeCode:u,activateCode:i,evaluateOnly:g,error:b,cycle:f,dirty:k,togglePlay:h,stop:M}=J({tune:e,autolink:!1,onEvent:a});t.useEffect(()=>{s&&g()},[e,s]);const[w,m]=t.useState(),[D,_]=re.useInView({threshold:.01}),E=t.useRef(),x=t.useMemo(()=>((_||!o)&&(E.current=!0),_||E.current),[_,o]);return G({view:w,pattern:r,active:f.started&&!u?.includes("strudel disable-highlighting"),getTime:()=>C.Tone.getTransport().seconds}),t.useLayoutEffect(()=>{if(n){const L=async q=>{(q.ctrlKey||q.altKey)&&(q.code==="Enter"?(q.preventDefault(),$(w),await i()):q.code==="Period"&&(f.stop(),q.preventDefault()))};return window.addEventListener("keydown",L,!0),()=>window.removeEventListener("keydown",L,!0)}},[n,r,l,i,f,w]),v.default.createElement("div",{className:N.container,ref:D},v.default.createElement("div",{className:N.header},v.default.createElement("div",{className:N.buttons},v.default.createElement("button",{className:H(N.button,f.started?"sc-animate-pulse":""),onClick:()=>h()},v.default.createElement(V,{type:f.started?"pause":"play"})),v.default.createElement("button",{className:H(k?N.button:N.buttonDisabled),onClick:()=>i()},v.default.createElement(V,{type:"refresh"}))),b&&v.default.createElement("div",{className:N.error},b.message)),v.default.createElement("div",{className:N.body},x&&v.default.createElement(K,{value:l,onChange:c,onViewChanged:m})))}function ye(e,o,s=.05,a=.1,n=.1){let l=0,c=0,r=10**4,u=.01;const i=m=>s=m(s);n=n||a/2;const g=()=>{const m=e(),D=m+a+n;for(c===0&&(c=m+u);c<D;)c=Math.round(c*r)/r,c>=m&&o(c,s,l),c<m&&console.log("TOO LATE",c),c+=s,l++};let b;const f=()=>{g(),b=setInterval(g,a*1e3)},k=()=>clearInterval(b);return{setDuration:i,start:f,stop:()=>{l=0,c=0,k()},pause:()=>k(),duration:s,getPhase:()=>c}}class we{worker;pattern;started=!1;cps=1;getTime;phase=0;constructor({interval:o,onTrigger:s,onError:a,getTime:n,latency:l=.1}){this.getTime=n;const c=r=>Math.round(r*1e3)/1e3;this.clock=ye(n,(r,u,i)=>{i===0&&(this.origin=r);const g=c(r-this.origin);this.phase=g-l;const b=c(g+u),f=n();try{this.pattern.queryArc(g,b).forEach(h=>{if(h.part.begin.equals(h.whole.begin)){const M=h.whole.begin+this.origin-f+l,w=h.duration*1;s?.(h,M,w)}})}catch(k){console.warn("scheduler error",k),a?.(k)}},o)}getPhase(){return this.phase}start(){if(!this.pattern)throw new Error("Scheduler: no pattern set! call .setPattern first.");this.clock.start(),this.started=!0}pause(){this.clock.stop(),delete this.origin,this.started=!1}stop(){delete this.origin,this.clock.stop(),this.started=!1}setPattern(o){this.pattern=o}setCps(o=1){this.cps=o}log(o,s,a){const n=a.filter(l=>l.hasOnset());console.log(`${o.toFixed(4)} - ${s.toFixed(4)} ${Array(n.length).fill("I").join("")}`)}}function Ee({defaultOutput:e,interval:o,getTime:s,code:a,evalOnMount:n=!1}){const[l,c]=t.useState(),[r,u]=t.useState(),[i,g]=t.useState(a),[b,f]=t.useState(),k=a!==i,h=t.useMemo(()=>new we({interval:o,onTrigger:e,onError:c,getTime:s}),[e,o]),M=t.useCallback(async()=>{if(!a){console.log("no code..");return}try{const{pattern:m}=await B.evaluate(a);g(a),h?.setPattern(m),f(m),u()}catch(m){u(m),console.warn("eval error",m)}},[a,h]),w=t.useRef();return t.useEffect(()=>{!w.current&&n&&(w.current=!0,M())},[M,n]),{schedulerError:l,scheduler:h,evalError:r,evaluate:M,activeCode:i,isDirty:k,pattern:b}}const ke=e=>t.useLayoutEffect(()=>(window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)),[e]);function Me(e){const{ready:o,connected:s,disconnected:a}=e,[n,l]=t.useState(!0),[c,r]=t.useState(T.WebMidi?.outputs||[]);return t.useEffect(()=>{T.enableWebMidi().then(()=>{T.WebMidi.addListener("connected",i=>{r([...T.WebMidi.outputs]),s?.(T.WebMidi,i)}),T.WebMidi.addListener("disconnected",i=>{r([...T.WebMidi.outputs]),a?.(T.WebMidi,i)}),o?.(T.WebMidi),l(!1)}).catch(i=>{if(i){console.error(i),console.warn("Web Midi could not be enabled..");return}})},[o,s,a,c]),{loading:n,outputs:c,outputByName:i=>T.WebMidi.getOutputByName(i)}}exports.CodeMirror=K;exports.MiniRepl=ve;exports.cx=H;exports.flash=$;exports.useCycle=U;exports.useHighlighting=G;exports.useKeydown=ke;exports.usePostMessage=Q;exports.useRepl=J;exports.useStrudel=Ee;exports.useWebMidi=Me;
|