From 92bf43e3a6447ebbcdd4f628d80284df88998122 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 5 Dec 2022 13:07:56 +0000 Subject: [PATCH] fix up imports from core, and remove circular deps that were breaking everything --- packages/core/draw.mjs | 4 +-- packages/core/evaluate.mjs | 4 +-- packages/core/index.mjs | 4 +-- packages/core/pianoroll.mjs | 4 +-- packages/core/speak.mjs | 4 +-- packages/eval/evaluate.mjs | 4 +-- packages/eval/shapeshifter.mjs | 4 +-- packages/eval/test/evaluate.test.mjs | 7 +++-- packages/mini/mini.mjs | 4 +-- packages/react/README.md | 5 ++-- packages/react/dist/index.cjs.js | 2 +- packages/react/dist/index.es.js | 27 ++++++++++--------- packages/react/examples/nano-repl/src/App.jsx | 7 ++--- packages/react/src/App.jsx | 3 ++- packages/react/src/hooks/useStrudel.mjs | 3 ++- packages/transpiler/index.mjs | 4 +-- packages/transpiler/transpiler.mjs | 3 ++- packages/webaudio/sampler.mjs | 3 ++- packages/webaudio/webaudio.mjs | 2 +- repl/src/Footer.jsx | 3 ++- repl/src/prebake.mjs | 4 +-- repl/src/runtime.mjs | 6 ++--- tutorial/MiniRepl.jsx | 8 +++--- 23 files changed, 62 insertions(+), 57 deletions(-) diff --git a/packages/core/draw.mjs b/packages/core/draw.mjs index 3bfcd37cd..feda4769a 100644 --- a/packages/core/draw.mjs +++ b/packages/core/draw.mjs @@ -4,8 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import core from './index.mjs'; -const { Pattern } = core; +import pattern from './pattern.mjs'; +const Pattern = pattern.Pattern; export const getDrawContext = (id = 'test-canvas') => { let canvas = document.querySelector('#' + id); diff --git a/packages/core/evaluate.mjs b/packages/core/evaluate.mjs index 63f7a58dc..1aca256f5 100644 --- a/packages/core/evaluate.mjs +++ b/packages/core/evaluate.mjs @@ -4,8 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import core from './index.mjs'; -const { isPattern, Pattern } = core; +import pattern from './pattern.mjs'; +const { isPattern, Pattern } = pattern; let scoped = false; export const evalScope = async (...args) => { diff --git a/packages/core/index.mjs b/packages/core/index.mjs index a063307db..6c5ba8493 100644 --- a/packages/core/index.mjs +++ b/packages/core/index.mjs @@ -28,8 +28,8 @@ import * as timespan from './timespan.mjs'; import * as ui from './ui.mjs'; import * as util from './util.mjs'; -const core = { ...controls, ...pattern, ...draw, ...euclid, - ...evaluate, ...hap, ...logger, ...repl, ...pianoroll, ...signal, ...speak, +const core = { drawLine, gist, logger, Fraction, ...controls, ...pattern, ...draw, ...euclid, + ...evaluate, ...hap, ...repl, ...pianoroll, ...signal, ...speak, ...state, ...time, ...timespan, ...ui, ...util }; export default core; diff --git a/packages/core/pianoroll.mjs b/packages/core/pianoroll.mjs index 94ad716ec..c8b4cbb00 100644 --- a/packages/core/pianoroll.mjs +++ b/packages/core/pianoroll.mjs @@ -4,8 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import core from './index.mjs'; -const { Pattern } = core; +import pattern from './pattern.mjs'; +const { Pattern } = pattern; const scale = (normalized, min, max) => normalized * (max - min) + min; const getValue = (e) => { diff --git a/packages/core/speak.mjs b/packages/core/speak.mjs index a997762a9..cd1324253 100644 --- a/packages/core/speak.mjs +++ b/packages/core/speak.mjs @@ -4,8 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import core from './index.mjs'; -const {Pattern, patternify2} = core; +import pattern from './pattern.mjs'; +const {Pattern, patternify2} = pattern; let synth; try { diff --git a/packages/eval/evaluate.mjs b/packages/eval/evaluate.mjs index 231322254..18dbee902 100644 --- a/packages/eval/evaluate.mjs +++ b/packages/eval/evaluate.mjs @@ -4,9 +4,9 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { evaluate as _evaluate } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; import shapeshifter from './shapeshifter.mjs'; export const evaluate = async (code) => { - return _evaluate(code, shapeshifter); + return core.evaluate(code, shapeshifter); }; diff --git a/packages/eval/shapeshifter.mjs b/packages/eval/shapeshifter.mjs index b26841def..b79f506d0 100644 --- a/packages/eval/shapeshifter.mjs +++ b/packages/eval/shapeshifter.mjs @@ -21,9 +21,9 @@ import { import shiftCodegen from 'shift-codegen'; const codegen = shiftCodegen.default || shiftCodegen; // parcel module resolution fuckup -import * as strudel from '@strudel.cycles/core'; +import strudel from '@strudel.cycles/core'; -const { Pattern } = strudel.pattern; +const { Pattern } = strudel; const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name); diff --git a/packages/eval/test/evaluate.test.mjs b/packages/eval/test/evaluate.test.mjs index b85bbd0cc..2b59e1d50 100644 --- a/packages/eval/test/evaluate.test.mjs +++ b/packages/eval/test/evaluate.test.mjs @@ -8,12 +8,11 @@ import { expect, describe, it } from 'vitest'; import { evaluate } from '../evaluate.mjs'; import { mini } from '@strudel.cycles/mini'; -import * as strudel from '@strudel.cycles/core'; -const { pattern, evalScope } = strudel; -const { fastcat } = pattern; +import strudel from '@strudel.cycles/core'; +const { fastcat, evalScope } = strudel; describe('evaluate', async () => { - await evalScope({ mini }, strudel, pattern); + await evalScope({ mini }, strudel); const ev = async (code) => (await evaluate(code)).pattern.firstCycleValues; it('Should evaluate strudel functions', async () => { expect(await ev('pure("c3")')).toEqual(['c3']); diff --git a/packages/mini/mini.mjs b/packages/mini/mini.mjs index 90a1cec1c..75ebb02c1 100644 --- a/packages/mini/mini.mjs +++ b/packages/mini/mini.mjs @@ -5,10 +5,10 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as krill from './krill-parser.js'; -import {pattern, rand, chooseInWith, Fraction} from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; // import { addMiniLocations } from '@strudel.cycles/eval/shapeshifter.mjs'; -const { pure, Pattern, stack, slowcat, sequence, timeCat, silence, reify } = pattern; +const { pure, Pattern, stack, slowcat, sequence, timeCat, silence, reify, rand, chooseInWith, Fraction } = core; var _seedState = 0; const randOffset = 0.0002; diff --git a/packages/react/README.md b/packages/react/README.md index a03dbf4d7..11fcaebc7 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -13,12 +13,13 @@ npm i @strudel.cycles/react Here is a minimal example of how to set up a MiniRepl: ```jsx -import { evalScope, controls } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const {evalScope} = core; import { MiniRepl } from '@strudel.cycles/react'; import { prebake } from '../repl/src/prebake.mjs'; evalScope( - controls, + core, import('@strudel.cycles/core'), import('@strudel.cycles/tonal'), import('@strudel.cycles/mini'), diff --git a/packages/react/dist/index.cjs.js b/packages/react/dist/index.cjs.js index cd672e9ea..d2ad10799 100644 --- a/packages/react/dist/index.cjs.js +++ b/packages/react/dist/index.cjs.js @@ -1 +1 @@ -"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react"),X=require("@uiw/react-codemirror"),p=require("@codemirror/view"),A=require("@codemirror/state"),Y=require("@codemirror/lang-javascript"),o=require("@lezer/highlight"),Z=require("@uiw/codemirror-themes"),ee=require("react-hook-inview"),B=require("@strudel.cycles/webaudio"),te=require("@strudel.cycles/core"),re=require("@strudel.cycles/transpiler"),I=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},n=I(t),oe=I(X),ae=Z.createTheme({theme:"dark",settings:{background:"#222",foreground:"#75baff",caret:"#ffcc00",selection:"rgba(128, 203, 196, 0.5)",selectionMatch:"#036dd626",lineHighlight:"#00000050",gutterBackground:"transparent",gutterForeground:"#8a919966"},styles:[{tag:o.tags.keyword,color:"#c792ea"},{tag:o.tags.operator,color:"#89ddff"},{tag:o.tags.special(o.tags.variableName),color:"#eeffff"},{tag:o.tags.typeName,color:"#c3e88d"},{tag:o.tags.atom,color:"#f78c6c"},{tag:o.tags.number,color:"#c3e88d"},{tag:o.tags.definition(o.tags.variableName),color:"#82aaff"},{tag:o.tags.string,color:"#c3e88d"},{tag:o.tags.special(o.tags.string),color:"#c3e88d"},{tag:o.tags.comment,color:"#7d8799"},{tag:o.tags.variableName,color:"#c792ea"},{tag:o.tags.tagName,color:"#c3e88d"},{tag:o.tags.bracket,color:"#525154"},{tag:o.tags.meta,color:"#ffcb6b"},{tag:o.tags.attributeName,color:"#c792ea"},{tag:o.tags.propertyName,color:"#c792ea"},{tag:o.tags.className,color:"#decb6b"},{tag:o.tags.invalid,color:"#ffffff"}]});const L=A.StateEffect.define(),ne=A.StateField.define({create(){return p.Decoration.none},update(e,r){try{for(let a of r.effects)if(a.is(L))if(a.value){const s=p.Decoration.mark({attributes:{style:"background-color: #FFCA2880"}});e=p.Decoration.set([s.range(0,r.newDoc.length)])}else e=p.Decoration.set([]);return e}catch(a){return console.warn("flash error",a),e}},provide:e=>p.EditorView.decorations.from(e)}),K=e=>{e.dispatch({effects:L.of(!0)}),setTimeout(()=>{e.dispatch({effects:L.of(!1)})},200)},x=A.StateEffect.define(),se=A.StateField.define({create(){return p.Decoration.none},update(e,r){try{for(let a of r.effects)if(a.is(x)){const s=a.value.map(c=>(c.context.locations||[]).map(({start:g,end:d})=>{const f=c.context.color||"#FFCA28";let i=r.newDoc.line(g.line).from+g.column,l=r.newDoc.line(d.line).from+d.column;const m=r.newDoc.length;return i>m||l>m?void 0:p.Decoration.mark({attributes:{style:`outline: 1.5px solid ${f};`}}).range(i,l)})).flat().filter(Boolean)||[];e=p.Decoration.set(s,!0)}return e}catch{return p.Decoration.set([])}},provide:e=>p.EditorView.decorations.from(e)}),ce=[Y.javascript(),ae,se,ne];function O({value:e,onChange:r,onViewChanged:a,onSelectionChange:s,options:c,editorDidMount:g}){const d=t.useCallback(l=>{r?.(l)},[r]),f=t.useCallback(l=>{a?.(l)},[a]),i=t.useCallback(l=>{l.selectionSet&&s&&s?.(l.state.selection)},[s]);return n.default.createElement(n.default.Fragment,null,n.default.createElement(oe.default,{value:e,onChange:d,onCreateEditor:f,onUpdate:i,extensions:ce}))}function T(...e){return e.filter(Boolean).join(" ")}function U({view:e,pattern:r,active:a,getTime:s}){const c=t.useRef([]),g=t.useRef();t.useEffect(()=>{if(e)if(r&&a){let f=function(){try{const i=s(),m=[Math.max(g.current||i,i-1/10,0),i+1/60];g.current=m[1],c.current=c.current.filter(h=>h.whole.end>i);const v=r.queryArc(...m).filter(h=>h.hasOnset());c.current=c.current.concat(v),e.dispatch({effects:x.of(c.current)})}catch{e.dispatch({effects:x.of([])})}d=requestAnimationFrame(f)},d=requestAnimationFrame(f);return()=>{cancelAnimationFrame(d)}}else c.current=[],e.dispatch({effects:x.of([])})},[r,a,e])}const ie="_container_3i85k_1",le="_header_3i85k_5",ue="_buttons_3i85k_9",de="_button_3i85k_9",fe="_buttonDisabled_3i85k_17",ge="_error_3i85k_21",me="_body_3i85k_25",E={container:ie,header:le,buttons:ue,button:de,buttonDisabled:fe,error:ge,body:me};function j({type:e}){return n.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:n.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:n.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:n.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 J(e){return t.useEffect(()=>(window.addEventListener("message",e),()=>window.removeEventListener("message",e)),[e]),t.useCallback(r=>window.postMessage(r,"*"),[])}function $({defaultOutput:e,interval:r,getTime:a,evalOnMount:s=!1,initialCode:c="",autolink:g=!1,beforeEval:d,afterEval:f,onEvalError:i,onToggle:l}){const m=t.useMemo(()=>he(),[]),[v,h]=t.useState(),[_,C]=t.useState(),[b,y]=t.useState(c),[M,P]=t.useState(),[k,D]=t.useState(),[S,N]=t.useState(!1),w=b!==M,{scheduler:R,evaluate:H,start:G,stop:z,pause:Q}=t.useMemo(()=>te.repl({interval:r,defaultOutput:e,onSchedulerError:h,onEvalError:u=>{C(u),i?.(u)},getTime:a,transpiler:re.transpiler,beforeEval:({code:u})=>{y(u),d?.()},afterEval:({pattern:u,code:F})=>{P(F),D(u),C(),h(),g&&(window.location.hash="#"+encodeURIComponent(btoa(F))),f?.()},onToggle:u=>{N(u),l?.(u)}}),[e,r,a]),W=J(({data:{from:u,type:F}})=>{F==="start"&&u!==m&&z()}),q=t.useCallback(async(u=!0)=>{await H(b,u),W({type:"start",from:m})},[H,b]),V=t.useRef();return t.useEffect(()=>{!V.current&&s&&b&&(V.current=!0,q())},[q,s,b]),t.useEffect(()=>()=>{R.stop()},[R]),{code:b,setCode:y,error:v||_,schedulerError:v,scheduler:R,evalError:_,evaluate:H,activateCode:q,activeCode:M,isDirty:w,pattern:k,started:S,start:G,stop:z,pause:Q,togglePlay:async()=>{S?R.pause():await q()}}}function he(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}const pe=()=>B.getAudioContext().currentTime;function be({tune:e,hideOutsideView:r=!1,init:a,enableKeyboard:s}){const{code:c,setCode:g,evaluate:d,activateCode:f,error:i,isDirty:l,activeCode:m,pattern:v,started:h,scheduler:_,togglePlay:C,stop:b}=$({initialCode:e,defaultOutput:B.webaudioOutput,getTime:pe}),[y,M]=t.useState(),[P,k]=ee.useInView({threshold:.01}),D=t.useRef(),S=t.useMemo(()=>((k||!r)&&(D.current=!0),k||D.current),[k,r]);return U({view:y,pattern:v,active:h&&!m?.includes("strudel disable-highlighting"),getTime:()=>_.getPhase()}),t.useLayoutEffect(()=>{if(s){const N=async w=>{(w.ctrlKey||w.altKey)&&(w.code==="Enter"?(w.preventDefault(),K(y),await f()):w.code==="Period"&&(b(),w.preventDefault()))};return window.addEventListener("keydown",N,!0),()=>window.removeEventListener("keydown",N,!0)}},[s,v,c,d,b,y]),n.default.createElement("div",{className:E.container,ref:P},n.default.createElement("div",{className:E.header},n.default.createElement("div",{className:E.buttons},n.default.createElement("button",{className:T(E.button,h?"sc-animate-pulse":""),onClick:()=>C()},n.default.createElement(j,{type:h?"pause":"play"})),n.default.createElement("button",{className:T(l?E.button:E.buttonDisabled),onClick:()=>f()},n.default.createElement(j,{type:"refresh"}))),i&&n.default.createElement("div",{className:E.error},i.message)),n.default.createElement("div",{className:E.body},S&&n.default.createElement(O,{value:c,onChange:g,onViewChanged:M})))}const ve=e=>t.useLayoutEffect(()=>(window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)),[e]);exports.CodeMirror=O;exports.MiniRepl=be;exports.cx=T;exports.flash=K;exports.useHighlighting=U;exports.useKeydown=ve;exports.usePostMessage=J;exports.useStrudel=$; +"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react"),X=require("@uiw/react-codemirror"),p=require("@codemirror/view"),A=require("@codemirror/state"),Y=require("@codemirror/lang-javascript"),o=require("@lezer/highlight"),Z=require("@uiw/codemirror-themes"),ee=require("react-hook-inview"),I=require("@strudel.cycles/webaudio"),te=require("@strudel.cycles/core"),re=require("@strudel.cycles/transpiler"),z=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},n=z(t),oe=z(X),ae=z(te),ne=Z.createTheme({theme:"dark",settings:{background:"#222",foreground:"#75baff",caret:"#ffcc00",selection:"rgba(128, 203, 196, 0.5)",selectionMatch:"#036dd626",lineHighlight:"#00000050",gutterBackground:"transparent",gutterForeground:"#8a919966"},styles:[{tag:o.tags.keyword,color:"#c792ea"},{tag:o.tags.operator,color:"#89ddff"},{tag:o.tags.special(o.tags.variableName),color:"#eeffff"},{tag:o.tags.typeName,color:"#c3e88d"},{tag:o.tags.atom,color:"#f78c6c"},{tag:o.tags.number,color:"#c3e88d"},{tag:o.tags.definition(o.tags.variableName),color:"#82aaff"},{tag:o.tags.string,color:"#c3e88d"},{tag:o.tags.special(o.tags.string),color:"#c3e88d"},{tag:o.tags.comment,color:"#7d8799"},{tag:o.tags.variableName,color:"#c792ea"},{tag:o.tags.tagName,color:"#c3e88d"},{tag:o.tags.bracket,color:"#525154"},{tag:o.tags.meta,color:"#ffcb6b"},{tag:o.tags.attributeName,color:"#c792ea"},{tag:o.tags.propertyName,color:"#c792ea"},{tag:o.tags.className,color:"#decb6b"},{tag:o.tags.invalid,color:"#ffffff"}]});const L=A.StateEffect.define(),se=A.StateField.define({create(){return p.Decoration.none},update(e,r){try{for(let a of r.effects)if(a.is(L))if(a.value){const s=p.Decoration.mark({attributes:{style:"background-color: #FFCA2880"}});e=p.Decoration.set([s.range(0,r.newDoc.length)])}else e=p.Decoration.set([]);return e}catch(a){return console.warn("flash error",a),e}},provide:e=>p.EditorView.decorations.from(e)}),K=e=>{e.dispatch({effects:L.of(!0)}),setTimeout(()=>{e.dispatch({effects:L.of(!1)})},200)},x=A.StateEffect.define(),ce=A.StateField.define({create(){return p.Decoration.none},update(e,r){try{for(let a of r.effects)if(a.is(x)){const s=a.value.map(c=>(c.context.locations||[]).map(({start:g,end:d})=>{const f=c.context.color||"#FFCA28";let i=r.newDoc.line(g.line).from+g.column,l=r.newDoc.line(d.line).from+d.column;const m=r.newDoc.length;return i>m||l>m?void 0:p.Decoration.mark({attributes:{style:`outline: 1.5px solid ${f};`}}).range(i,l)})).flat().filter(Boolean)||[];e=p.Decoration.set(s,!0)}return e}catch{return p.Decoration.set([])}},provide:e=>p.EditorView.decorations.from(e)}),ie=[Y.javascript(),ne,ce,se];function O({value:e,onChange:r,onViewChanged:a,onSelectionChange:s,options:c,editorDidMount:g}){const d=t.useCallback(l=>{r?.(l)},[r]),f=t.useCallback(l=>{a?.(l)},[a]),i=t.useCallback(l=>{l.selectionSet&&s&&s?.(l.state.selection)},[s]);return n.default.createElement(n.default.Fragment,null,n.default.createElement(oe.default,{value:e,onChange:d,onCreateEditor:f,onUpdate:i,extensions:ie}))}function T(...e){return e.filter(Boolean).join(" ")}function U({view:e,pattern:r,active:a,getTime:s}){const c=t.useRef([]),g=t.useRef();t.useEffect(()=>{if(e)if(r&&a){let f=function(){try{const i=s(),m=[Math.max(g.current||i,i-1/10,0),i+1/60];g.current=m[1],c.current=c.current.filter(h=>h.whole.end>i);const v=r.queryArc(...m).filter(h=>h.hasOnset());c.current=c.current.concat(v),e.dispatch({effects:x.of(c.current)})}catch{e.dispatch({effects:x.of([])})}d=requestAnimationFrame(f)},d=requestAnimationFrame(f);return()=>{cancelAnimationFrame(d)}}else c.current=[],e.dispatch({effects:x.of([])})},[r,a,e])}const le="_container_3i85k_1",ue="_header_3i85k_5",de="_buttons_3i85k_9",fe="_button_3i85k_9",ge="_buttonDisabled_3i85k_17",me="_error_3i85k_21",he="_body_3i85k_25",E={container:le,header:ue,buttons:de,button:fe,buttonDisabled:ge,error:me,body:he};function B({type:e}){return n.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:n.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:n.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:n.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 J(e){return t.useEffect(()=>(window.addEventListener("message",e),()=>window.removeEventListener("message",e)),[e]),t.useCallback(r=>window.postMessage(r,"*"),[])}const pe=ae.default.repl;function $({defaultOutput:e,interval:r,getTime:a,evalOnMount:s=!1,initialCode:c="",autolink:g=!1,beforeEval:d,afterEval:f,onEvalError:i,onToggle:l}){const m=t.useMemo(()=>be(),[]),[v,h]=t.useState(),[k,C]=t.useState(),[b,y]=t.useState(c),[M,P]=t.useState(),[_,D]=t.useState(),[S,N]=t.useState(!1),w=b!==M,{scheduler:R,evaluate:H,start:G,stop:V,pause:Q}=t.useMemo(()=>pe({interval:r,defaultOutput:e,onSchedulerError:h,onEvalError:u=>{C(u),i?.(u)},getTime:a,transpiler:re.transpiler,beforeEval:({code:u})=>{y(u),d?.()},afterEval:({pattern:u,code:F})=>{P(F),D(u),C(),h(),g&&(window.location.hash="#"+encodeURIComponent(btoa(F))),f?.()},onToggle:u=>{N(u),l?.(u)}}),[e,r,a]),W=J(({data:{from:u,type:F}})=>{F==="start"&&u!==m&&V()}),q=t.useCallback(async(u=!0)=>{await H(b,u),W({type:"start",from:m})},[H,b]),j=t.useRef();return t.useEffect(()=>{!j.current&&s&&b&&(j.current=!0,q())},[q,s,b]),t.useEffect(()=>()=>{R.stop()},[R]),{code:b,setCode:y,error:v||k,schedulerError:v,scheduler:R,evalError:k,evaluate:H,activateCode:q,activeCode:M,isDirty:w,pattern:_,started:S,start:G,stop:V,pause:Q,togglePlay:async()=>{S?R.pause():await q()}}}function be(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}const ve=()=>I.getAudioContext().currentTime;function we({tune:e,hideOutsideView:r=!1,init:a,enableKeyboard:s}){const{code:c,setCode:g,evaluate:d,activateCode:f,error:i,isDirty:l,activeCode:m,pattern:v,started:h,scheduler:k,togglePlay:C,stop:b}=$({initialCode:e,defaultOutput:I.webaudioOutput,getTime:ve}),[y,M]=t.useState(),[P,_]=ee.useInView({threshold:.01}),D=t.useRef(),S=t.useMemo(()=>((_||!r)&&(D.current=!0),_||D.current),[_,r]);return U({view:y,pattern:v,active:h&&!m?.includes("strudel disable-highlighting"),getTime:()=>k.getPhase()}),t.useLayoutEffect(()=>{if(s){const N=async w=>{(w.ctrlKey||w.altKey)&&(w.code==="Enter"?(w.preventDefault(),K(y),await f()):w.code==="Period"&&(b(),w.preventDefault()))};return window.addEventListener("keydown",N,!0),()=>window.removeEventListener("keydown",N,!0)}},[s,v,c,d,b,y]),n.default.createElement("div",{className:E.container,ref:P},n.default.createElement("div",{className:E.header},n.default.createElement("div",{className:E.buttons},n.default.createElement("button",{className:T(E.button,h?"sc-animate-pulse":""),onClick:()=>C()},n.default.createElement(B,{type:h?"pause":"play"})),n.default.createElement("button",{className:T(l?E.button:E.buttonDisabled),onClick:()=>f()},n.default.createElement(B,{type:"refresh"}))),i&&n.default.createElement("div",{className:E.error},i.message)),n.default.createElement("div",{className:E.body},S&&n.default.createElement(O,{value:c,onChange:g,onViewChanged:M})))}const Ee=e=>t.useLayoutEffect(()=>(window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)),[e]);exports.CodeMirror=O;exports.MiniRepl=we;exports.cx=T;exports.flash=K;exports.useHighlighting=U;exports.useKeydown=Ee;exports.usePostMessage=J;exports.useStrudel=$; diff --git a/packages/react/dist/index.es.js b/packages/react/dist/index.es.js index 499895c35..e0d7be869 100644 --- a/packages/react/dist/index.es.js +++ b/packages/react/dist/index.es.js @@ -7,7 +7,7 @@ import { tags as r } from "@lezer/highlight"; import { createTheme as Z } from "@uiw/codemirror-themes"; import { useInView as ee } from "react-hook-inview"; import { webaudioOutput as te, getAudioContext as re } from "@strudel.cycles/webaudio"; -import { repl as oe } from "@strudel.cycles/core"; +import oe from "@strudel.cycles/core"; import { transpiler as ne } from "@strudel.cycles/transpiler"; const ae = Z({ theme: "dark", @@ -177,7 +177,8 @@ function O({ type: e }) { function Ee(e) { return L(() => (window.addEventListener("message", e), () => window.removeEventListener("message", e)), [e]), _((t) => window.postMessage(t, "*"), []); } -function we({ +const we = oe.repl; +function ye({ defaultOutput: e, interval: t, getTime: o, @@ -189,8 +190,8 @@ function we({ onEvalError: c, onToggle: i }) { - const m = V(() => ye(), []), [h, g] = w(), [C, N] = w(), [p, y] = w(s), [M, S] = w(), [k, D] = w(), [F, x] = w(!1), b = p !== M, { scheduler: A, evaluate: T, start: J, stop: q, pause: Q } = V( - () => oe({ + const m = V(() => ke(), []), [h, g] = w(), [C, N] = w(), [p, y] = w(s), [M, S] = w(), [k, D] = w(), [F, x] = w(!1), b = p !== M, { scheduler: A, evaluate: T, start: J, stop: q, pause: Q } = V( + () => we({ interval: t, defaultOutput: e, onSchedulerError: g, @@ -243,11 +244,11 @@ function we({ } }; } -function ye() { +function ke() { return Math.floor((1 + Math.random()) * 65536).toString(16).substring(1); } -const ke = () => re().currentTime; -function Se({ tune: e, hideOutsideView: t = !1, init: o, enableKeyboard: a }) { +const _e = () => re().currentTime; +function Te({ tune: e, hideOutsideView: t = !1, init: o, enableKeyboard: a }) { const { code: s, setCode: f, @@ -261,10 +262,10 @@ function Se({ tune: e, hideOutsideView: t = !1, init: o, enableKeyboard: a }) { scheduler: C, togglePlay: N, stop: p - } = we({ + } = ye({ initialCode: e, defaultOutput: te, - getTime: ke + getTime: _e }), [y, M] = w(), [S, k] = ee({ threshold: 0.01 }), D = H(), F = V(() => ((k || !t) && (D.current = !0), k || D.current), [k, t]); @@ -307,14 +308,14 @@ function Se({ tune: e, hideOutsideView: t = !1, init: o, enableKeyboard: a }) { onViewChanged: M }))); } -const Te = (e) => j(() => (window.addEventListener("keydown", e, !0), () => window.removeEventListener("keydown", e, !0)), [e]); +const Ve = (e) => j(() => (window.addEventListener("keydown", e, !0), () => window.removeEventListener("keydown", e, !0)), [e]); export { de as CodeMirror, - Se as MiniRepl, + Te as MiniRepl, K as cx, ce as flash, ue as useHighlighting, - Te as useKeydown, + Ve as useKeydown, Ee as usePostMessage, - we as useStrudel + ye as useStrudel }; diff --git a/packages/react/examples/nano-repl/src/App.jsx b/packages/react/examples/nano-repl/src/App.jsx index 07c46f3ed..ae7518aa6 100644 --- a/packages/react/examples/nano-repl/src/App.jsx +++ b/packages/react/examples/nano-repl/src/App.jsx @@ -1,4 +1,5 @@ -import { evalScope, controls } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const { evalScope } = core; import { getAudioContext, panic, webaudioOutput } from '@strudel.cycles/webaudio'; import { useCallback, useState } from 'react'; import CodeMirror, { flash } from '../../../src/components/CodeMirror6'; @@ -10,8 +11,8 @@ import './style.css'; // TODO: only import stuff when play is pressed? evalScope( - controls, - import('@strudel.cycles/core'), + core, + // import('@strudel.cycles/core'), // import('@strudel.cycles/tone'), // import('@strudel.cycles/midi'), // TODO: find out why midi loads tone.js import('@strudel.cycles/tonal'), diff --git a/packages/react/src/App.jsx b/packages/react/src/App.jsx index 911fca0ba..e984b28e0 100644 --- a/packages/react/src/App.jsx +++ b/packages/react/src/App.jsx @@ -1,7 +1,8 @@ import React from 'react'; import { MiniRepl } from './components/MiniRepl'; import 'tailwindcss/tailwind.css'; -import { controls, evalScope } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const {controls, evalScope} = core; evalScope( controls, diff --git a/packages/react/src/hooks/useStrudel.mjs b/packages/react/src/hooks/useStrudel.mjs index 823264150..f3ef0f7aa 100644 --- a/packages/react/src/hooks/useStrudel.mjs +++ b/packages/react/src/hooks/useStrudel.mjs @@ -1,5 +1,6 @@ import { useRef, useCallback, useEffect, useMemo, useState } from 'react'; -import { repl } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const repl = core.repl import { transpiler } from '@strudel.cycles/transpiler'; import usePostMessage from './usePostMessage.mjs'; diff --git a/packages/transpiler/index.mjs b/packages/transpiler/index.mjs index 4832a423d..dafbce985 100644 --- a/packages/transpiler/index.mjs +++ b/packages/transpiler/index.mjs @@ -1,5 +1,5 @@ -import { evaluate as _evaluate } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; import { transpiler } from './transpiler.mjs'; export * from './transpiler.mjs'; -export const evaluate = (code) => _evaluate(code, transpiler); +export const evaluate = (code) => core.evaluate(code, transpiler); diff --git a/packages/transpiler/transpiler.mjs b/packages/transpiler/transpiler.mjs index a0b245122..5ae54bd90 100644 --- a/packages/transpiler/transpiler.mjs +++ b/packages/transpiler/transpiler.mjs @@ -1,7 +1,8 @@ import escodegen from 'escodegen'; import { parse } from 'acorn'; import { walk } from 'estree-walker'; -import { isNote } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const { isNote } = core; export function transpiler(input, options = {}) { const { wrapAsync = false, addReturn = true, simpleLocs = false } = options; diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 59dffb7c5..237b3708c 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -1,4 +1,5 @@ -import { logger } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const logger = core.logger; const bufferCache = {}; // string: Promise const loadCache = {}; // string: Promise diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 4ebc9116c..b13156c19 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import strudel from '@strudel.cycles/core'; -import { fromMidi, logger, toMidi } from '@strudel.cycles/core'; +const { fromMidi, logger, toMidi } = strudel; import './feedbackdelay.mjs'; import './reverb.mjs'; import { getSampleBufferSource } from './sampler.mjs'; diff --git a/repl/src/Footer.jsx b/repl/src/Footer.jsx index b3f0ddb0f..236381c1f 100644 --- a/repl/src/Footer.jsx +++ b/repl/src/Footer.jsx @@ -1,5 +1,6 @@ import XMarkIcon from '@heroicons/react/20/solid/XMarkIcon'; -import { logger } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; +const { logger } = core; import { cx } from '@strudel.cycles/react'; import { nanoid } from 'nanoid'; import React, { useContext, useCallback, useLayoutEffect, useRef, useState } from 'react'; diff --git a/repl/src/prebake.mjs b/repl/src/prebake.mjs index 75b490a33..4fb8e4c61 100644 --- a/repl/src/prebake.mjs +++ b/repl/src/prebake.mjs @@ -1,5 +1,5 @@ -import { pattern, toMidi } from '@strudel.cycles/core'; -const { Pattern } = pattern; +import core from '@strudel.cycles/core'; +const { Pattern, toMidi } = core; import { samples } from '@strudel.cycles/webaudio'; export async function prebake({ isMock = false, baseDir = '.' } = {}) { diff --git a/repl/src/runtime.mjs b/repl/src/runtime.mjs index d95c8f995..2aa643bb1 100644 --- a/repl/src/runtime.mjs +++ b/repl/src/runtime.mjs @@ -5,9 +5,8 @@ // import * as tunes from './tunes.mjs'; // import { evaluate } from '@strudel.cycles/eval'; import { evaluate } from '@strudel.cycles/transpiler'; -import { evalScope } from '@strudel.cycles/core'; -import * as strudel from '@strudel.cycles/core'; -const { Pattern } = strudel.pattern; +import strudel from '@strudel.cycles/core'; +const { Pattern, evalScope } = strudel; import * as webaudio from '@strudel.cycles/webaudio'; import controls from '@strudel.cycles/core/controls.mjs'; // import gist from '@strudel.cycles/core/gist.js'; @@ -157,7 +156,6 @@ const loadSoundfont = () => {}; evalScope( // Tone, strudel, - strudel.pattern, Pattern.prototype.bootstrap(), toneHelpersMocked, uiHelpersMocked, diff --git a/tutorial/MiniRepl.jsx b/tutorial/MiniRepl.jsx index c86a83fd4..051e5e503 100644 --- a/tutorial/MiniRepl.jsx +++ b/tutorial/MiniRepl.jsx @@ -1,4 +1,4 @@ -import { evalScope, controls } from '@strudel.cycles/core'; +import core from '@strudel.cycles/core'; import { MiniRepl as _MiniRepl } from '@strudel.cycles/react'; import { samples } from '@strudel.cycles/webaudio'; import { prebake } from '../repl/src/prebake.mjs'; @@ -7,9 +7,9 @@ fetch('https://strudel.tidalcycles.org/EmuSP12.json') .then((res) => res.json()) .then((json) => samples(json, 'https://strudel.tidalcycles.org/EmuSP12/')); -evalScope( - controls, - import('@strudel.cycles/core'), +core.evalScope( + core, + // import('@strudel.cycles/core'), // import('@strudel.cycles/tone'), import('@strudel.cycles/tonal'), import('@strudel.cycles/mini'),