remove hooks package for now

This commit is contained in:
Felix Roos
2022-03-25 22:04:43 +01:00
parent 65deb7df1d
commit 43d8f46eab
17 changed files with 151 additions and 2710 deletions
+4 -67
View File
@@ -1,70 +1,7 @@
# Getting Started with Create React App
# Strudel REPL
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
TBD
## Available Scripts
## Dev Notes
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
Always run `npm i --legacy-peer-deps`, otherwise `@tonejs/piano` will break.
+34 -79
View File
@@ -12,15 +12,16 @@
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"codemirror": "^5.65.2",
"events": "^3.3.0",
"react": "^17.0.2",
"react-codemirror2": "^7.2.1",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"tone": "^14.7.77",
"web-vitals": "^2.1.4",
"webmidi": "^2.5.1"
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@mdx-js/react": "^1.6.22",
"@parcel/transformer-mdx": "^2.3.1",
"autoprefixer": "^10.4.4",
"parcel": "^2.3.1",
@@ -2813,7 +2814,6 @@
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz",
"integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==",
"dev": true,
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
@@ -18462,14 +18462,6 @@
"node": ">=10.4"
}
},
"node_modules/webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg==",
"engines": {
"node": ">0.6.x"
}
},
"node_modules/webpack": {
"version": "5.70.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
@@ -21286,9 +21278,7 @@
"version": "1.6.22",
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz",
"integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==",
"dev": true,
"peer": true,
"requires": {}
"dev": true
},
"@mdx-js/util": {
"version": "1.6.22",
@@ -23486,14 +23476,12 @@
"acorn-import-assertions": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
"requires": {}
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw=="
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"requires": {}
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
},
"acorn-node": {
"version": "1.8.2",
@@ -23588,8 +23576,7 @@
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"requires": {}
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"ansi-escapes": {
"version": "4.3.2",
@@ -23917,8 +23904,7 @@
"babel-plugin-named-asset-import": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz",
"integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==",
"requires": {}
"integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q=="
},
"babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
@@ -24715,8 +24701,7 @@
"css-prefers-color-scheme": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
"integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
"requires": {}
"integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA=="
},
"css-select": {
"version": "4.2.1",
@@ -24820,8 +24805,7 @@
"cssnano-utils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
"requires": {}
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA=="
},
"csso": {
"version": "4.2.0",
@@ -25728,8 +25712,7 @@
"eslint-plugin-react-hooks": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz",
"integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==",
"requires": {}
"integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA=="
},
"eslint-plugin-testing-library": {
"version": "5.1.0",
@@ -26732,8 +26715,7 @@
"icss-utils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
"requires": {}
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="
},
"idb": {
"version": "6.1.5",
@@ -27849,8 +27831,7 @@
"jest-pnp-resolver": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
"requires": {}
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w=="
},
"jest-regex-util": {
"version": "27.5.1",
@@ -29587,8 +29568,7 @@
"postcss-browser-comments": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz",
"integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==",
"requires": {}
"integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg=="
},
"postcss-calc": {
"version": "8.2.4",
@@ -29653,8 +29633,7 @@
"postcss-custom-media": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz",
"integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==",
"requires": {}
"integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g=="
},
"postcss-custom-properties": {
"version": "12.1.5",
@@ -29683,26 +29662,22 @@
"postcss-discard-comments": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz",
"integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==",
"requires": {}
"integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ=="
},
"postcss-discard-duplicates": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
"requires": {}
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw=="
},
"postcss-discard-empty": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
"requires": {}
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A=="
},
"postcss-discard-overridden": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
"requires": {}
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw=="
},
"postcss-double-position-gradients": {
"version": "3.1.1",
@@ -29724,8 +29699,7 @@
"postcss-flexbugs-fixes": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz",
"integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==",
"requires": {}
"integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ=="
},
"postcss-focus-visible": {
"version": "6.0.4",
@@ -29746,14 +29720,12 @@
"postcss-font-variant": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
"integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
"requires": {}
"integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA=="
},
"postcss-gap-properties": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz",
"integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==",
"requires": {}
"integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ=="
},
"postcss-image-set-function": {
"version": "4.0.6",
@@ -29766,8 +29738,7 @@
"postcss-initial": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
"integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
"requires": {}
"integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ=="
},
"postcss-js": {
"version": "4.0.0",
@@ -29808,14 +29779,12 @@
"postcss-logical": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
"integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
"requires": {}
"integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g=="
},
"postcss-media-minmax": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
"integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
"requires": {}
"integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ=="
},
"postcss-merge-longhand": {
"version": "5.1.3",
@@ -29876,8 +29845,7 @@
"postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
"requires": {}
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw=="
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
@@ -29934,8 +29902,7 @@
"postcss-normalize-charset": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
"requires": {}
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg=="
},
"postcss-normalize-display-values": {
"version": "5.1.0",
@@ -30020,14 +29987,12 @@
"postcss-overflow-shorthand": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz",
"integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==",
"requires": {}
"integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg=="
},
"postcss-page-break": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz",
"integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==",
"requires": {}
"integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ=="
},
"postcss-place": {
"version": "7.0.4",
@@ -30115,8 +30080,7 @@
"postcss-replace-overflow-wrap": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz",
"integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==",
"requires": {}
"integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw=="
},
"postcss-selector-not": {
"version": "5.0.0",
@@ -30476,8 +30440,7 @@
"react-codemirror2": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.2.1.tgz",
"integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==",
"requires": {}
"integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw=="
},
"react-dev-utils": {
"version": "12.0.0",
@@ -31569,8 +31532,7 @@
"style-loader": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
"integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
"requires": {}
"integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ=="
},
"style-to-object": {
"version": "0.3.0",
@@ -32387,11 +32349,6 @@
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
},
"webmidi": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/webmidi/-/webmidi-2.5.3.tgz",
"integrity": "sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg=="
},
"webpack": {
"version": "5.70.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
@@ -32571,8 +32528,7 @@
"ws": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==",
"requires": {}
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg=="
}
}
},
@@ -33006,8 +32962,7 @@
"ws": {
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
"requires": {}
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A=="
},
"xml-name-validator": {
"version": "3.0.0",
+7 -5
View File
@@ -2,18 +2,19 @@
"name": "@strudel/repl",
"version": "0.1.0",
"private": true,
"homepage": "https://strudel.tidalcycles.org",
"dependencies": {
"@testing-library/jest-dom": "^5.16.3",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"codemirror": "^5.65.2",
"events": "^3.3.0",
"react": "^17.0.2",
"react-codemirror2": "^7.2.1",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"tone": "^14.7.77",
"web-vitals": "^2.1.4",
"webmidi": "^2.5.1"
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
@@ -42,10 +43,11 @@
]
},
"devDependencies": {
"@mdx-js/react": "^1.6.22",
"@parcel/transformer-mdx": "^2.3.1",
"autoprefixer": "^10.4.4",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23",
"parcel": "^2.3.1",
"@parcel/transformer-mdx": "^2.3.1"
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23"
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ import logo from './logo.svg';
import playStatic from './static.mjs';
import { defaultSynth } from '@strudel/tone';
import * as tunes from './tunes.mjs';
import useRepl from '@strudel/hooks/useRepl.mjs';
import useRepl from './useRepl.mjs';
import { useWebMidi } from './useWebMidi';
import './App.css'
+1 -1
View File
@@ -1,6 +1,6 @@
import React, { useCallback, useMemo, useState } from 'react';
import { Tone } from '@strudel/tone';
import useRepl from '@strudel/hooks/useRepl.mjs';
import useRepl from '../useRepl.mjs';
import CodeMirror, { markEvent } from '../CodeMirror';
import cx from '../cx';
+86
View File
@@ -0,0 +1,86 @@
import { useEffect, useState } from 'react';
import { Tone } from '@strudel/tone';
import { State, TimeSpan } from '@strudel/core';
/* export declare interface UseCycleProps {
onEvent: ToneEventCallback<any>;
onQuery?: (state: State) => Hap[];
onSchedule?: (events: Hap[], cycle: number) => void;
onDraw?: ToneEventCallback<any>;
ready?: boolean; // if false, query will not be called on change props
} */
// function useCycle(props: UseCycleProps) {
function useCycle(props) {
// onX must use useCallback!
const { onEvent, onQuery, onSchedule, ready = true, onDraw } = props;
const [started, setStarted] = useState(false);
const cycleDuration = 1;
const activeCycle = () => Math.floor(Tone.getTransport().seconds / cycleDuration);
// pull events with onQuery + count up to next cycle
const query = (cycle = activeCycle()) => {
const timespan = new TimeSpan(cycle, cycle + 1);
const events = onQuery?.(new State(timespan)) || [];
onSchedule?.(events, cycle);
// cancel events after current query. makes sure no old events are player for rescheduled cycles
// console.log('schedule', cycle);
// query next cycle in the middle of the current
const cancelFrom = timespan.begin.valueOf();
Tone.getTransport().cancel(cancelFrom);
// const queryNextTime = (cycle + 1) * cycleDuration - 0.1;
const queryNextTime = (cycle + 1) * cycleDuration - 0.5;
// if queryNextTime would be before current time, execute directly (+0.1 for safety that it won't miss)
const t = Math.max(Tone.getTransport().seconds, queryNextTime) + 0.1;
Tone.getTransport().schedule(() => {
query(cycle + 1);
}, t);
// schedule events for next cycle
events
?.filter((event) => event.part.begin.equals(event.whole.begin))
.forEach((event) => {
Tone.getTransport().schedule((time) => {
const toneEvent = {
time: event.whole.begin.valueOf(),
duration: event.whole.end.sub(event.whole.begin).valueOf(),
value: event.value,
context: event.context,
};
onEvent(time, toneEvent);
Tone.Draw.schedule(() => {
// do drawing or DOM manipulation here
onDraw?.(time, toneEvent);
}, time);
}, event.part.begin.valueOf());
});
};
useEffect(() => {
ready && query();
}, [onEvent, onSchedule, onQuery, onDraw, ready]);
const start = async () => {
setStarted(true);
await Tone.start();
Tone.getTransport().start('+0.1');
};
const stop = () => {
Tone.getTransport().pause();
setStarted(false);
};
const toggle = () => (started ? stop() : start());
return {
start,
stop,
onEvent,
started,
setStarted,
toggle,
query,
activeCycle,
};
}
export default useCycle;
+11
View File
@@ -0,0 +1,11 @@
import { useEffect } from 'react';
function usePostMessage(listener) {
useEffect(() => {
window.addEventListener('message', listener);
return () => window.removeEventListener('message', listener);
}, [listener]);
return (data) => window.postMessage(data, '*');
}
export default usePostMessage;
+174
View File
@@ -0,0 +1,174 @@
import { useCallback, useState, useMemo } from 'react';
import { evaluate } from '@strudel/eval';
import { getPlayableNoteValue } from '@strudel/core/util.mjs';
import useCycle from './useCycle.mjs';
import usePostMessage from './usePostMessage.mjs';
let s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }) {
const id = useMemo(() => s4(), []);
const [code, setCode] = useState(tune);
const [activeCode, setActiveCode] = useState();
const [log, setLog] = useState('');
const [error, setError] = useState();
const [pending, setPending] = useState(false);
const [hash, setHash] = useState('');
const [pattern, setPattern] = useState();
const dirty = code !== activeCode || error;
const generateHash = () => encodeURIComponent(btoa(code));
const activateCode = async (_code = code) => {
if (activeCode && !dirty) {
setError(undefined);
cycle.start();
return;
}
try {
setPending(true);
const parsed = await evaluate(_code);
cycle.start();
broadcast({ type: 'start', from: id });
setPattern(() => parsed.pattern);
if (autolink) {
window.location.hash = '#' + encodeURIComponent(btoa(code));
}
setHash(generateHash());
setError(undefined);
setActiveCode(_code);
setPending(false);
} catch (err) {
err.message = 'evaluation error: ' + err.message;
console.warn(err);
setError(err);
}
};
const pushLog = (message) => setLog((log) => log + `${log ? '\n\n' : ''}${message}`);
// logs events of cycle
const logCycle = (_events, cycle) => {
if (_events.length) {
// pushLog(`# cycle ${cycle}\n` + _events.map((e: any) => e.show()).join('\n'));
}
};
// below block allows disabling the highlighting by including "strudel disable-highlighting" in the code (as comment)
onDraw = useMemo(() => {
if (activeCode && !activeCode.includes('strudel disable-highlighting')) {
return onDraw;
}
}, [activeCode]);
// cycle hook to control scheduling
const cycle = useCycle({
onDraw,
onEvent: useCallback(
(time, event) => {
try {
onEvent?.(event);
const { onTrigger, velocity } = event.context;
if (!onTrigger) {
if (defaultSynth) {
const note = getPlayableNoteValue(event);
defaultSynth.triggerAttackRelease(note, event.duration, time, velocity);
} else {
throw new Error('no defaultSynth passed to useRepl.');
}
/* console.warn('no instrument chosen', event);
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
} else {
onTrigger(time, event);
}
} catch (err) {
console.warn(err);
err.message = 'unplayable event: ' + err?.message;
pushLog(err.message); // not with setError, because then we would have to setError(undefined) on next playable event
}
},
[onEvent]
),
onQuery: useCallback(
(state) => {
try {
return pattern?.query(state) || [];
} catch (err) {
console.warn(err);
err.message = 'query error: ' + err.message;
setError(err);
return [];
}
},
[pattern]
),
onSchedule: useCallback((_events, cycle) => logCycle(_events, cycle), [pattern]),
ready: !!pattern && !!activeCode,
});
const broadcast = usePostMessage(({ data: { from, type } }) => {
if (type === 'start' && from !== id) {
// console.log('message', from, type);
cycle.setStarted(false);
setActiveCode(undefined);
}
});
// set active pattern on ctrl+enter
/* useLayoutEffect(() => {
// TODO: make sure this is only fired when editor has focus
const handleKeyPress = (e: any) => {
if (e.ctrlKey || e.altKey) {
switch (e.code) {
case 'Enter':
activateCode();
!cycle.started && cycle.start();
break;
case 'Period':
cycle.stop();
}
}
};
document.addEventListener('keypress', handleKeyPress);
return () => document.removeEventListener('keypress', handleKeyPress);
}, [pattern, code]); */
/* useWebMidi({
ready: useCallback(({ outputs }) => {
pushLog(`WebMidi ready! Just add .midi(${outputs.map((o) => `'${o.name}'`).join(' | ')}) to the pattern. `);
}, []),
connected: useCallback(({ outputs }) => {
pushLog(`Midi device connected! Available: ${outputs.map((o) => `'${o.name}'`).join(', ')}`);
}, []),
disconnected: useCallback(({ outputs }) => {
pushLog(`Midi device disconnected! Available: ${outputs.map((o) => `'${o.name}'`).join(', ')}`);
}, []),
}); */
const togglePlay = () => {
if (!cycle.started) {
activateCode();
} else {
cycle.stop();
}
};
return {
pending,
code,
setCode,
pattern,
error,
cycle,
setPattern,
dirty,
log,
togglePlay,
activateCode,
activeCode,
pushLog,
hash,
};
}
export default useRepl;