mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
add basic repl
This commit is contained in:
parent
83d06ec2af
commit
71a3bdfeac
4
repl/.gitignore
vendored
Normal file
4
repl/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.snowpack
|
||||
build
|
||||
node_modules
|
||||
.DS_Store
|
||||
25
repl/README.md
Normal file
25
repl/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Strudel REPL
|
||||
|
||||
> ✨ Bootstrapped with Create Snowpack App (CSA).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
### npm start
|
||||
|
||||
Runs the app in the development mode.
|
||||
Open http://localhost:8080 to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### npm run build
|
||||
|
||||
Builds a static copy of your site to the `build/` folder.
|
||||
Your app is ready to be deployed!
|
||||
|
||||
**For the best production performance:** Add a build bundler plugin like "@snowpack/plugin-webpack" to your `snowpack.config.mjs` config file.
|
||||
|
||||
### npm test
|
||||
|
||||
Launches the application test runner.
|
||||
Run with the `--watch` flag (`npm test -- --watch`) to run in interactive watch mode.
|
||||
14828
repl/package-lock.json
generated
Normal file
14828
repl/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
repl/package.json
Normal file
35
repl/package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"scripts": {
|
||||
"start": "snowpack dev",
|
||||
"build": "snowpack build",
|
||||
"test": "web-test-runner \"src/**/*.test.tsx\"",
|
||||
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
|
||||
"lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@snowpack/plugin-dotenv": "^2.1.0",
|
||||
"@snowpack/plugin-postcss": "^1.4.3",
|
||||
"@snowpack/plugin-react-refresh": "^2.5.0",
|
||||
"@snowpack/plugin-typescript": "^1.2.1",
|
||||
"@snowpack/web-test-runner-plugin": "^0.2.2",
|
||||
"@tailwindcss/forms": "^0.4.0",
|
||||
"@testing-library/react": "^11.2.6",
|
||||
"@types/chai": "^4.2.17",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@types/react": "^17.0.4",
|
||||
"@types/react-dom": "^17.0.3",
|
||||
"@types/snowpack-env": "^2.3.3",
|
||||
"@web/test-runner": "^0.13.3",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"chai": "^4.3.4",
|
||||
"postcss": "^8.4.6",
|
||||
"prettier": "^2.2.1",
|
||||
"snowpack": "^3.3.7",
|
||||
"tailwindcss": "^3.0.18",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
8
repl/postcss.config.js
Normal file
8
repl/postcss.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
// postcss.config.js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
// other plugins can go here, such as autoprefixer
|
||||
},
|
||||
};
|
||||
BIN
repl/public/favicon.ico
Normal file
BIN
repl/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
3
repl/public/global.css
Normal file
3
repl/public/global.css
Normal file
@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
16
repl/public/index.html
Normal file
16
repl/public/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="/global.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Strudel REPL" />
|
||||
<title>Strudel REPL</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script type="module" src="/dist/index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
38
repl/snowpack.config.mjs
Normal file
38
repl/snowpack.config.mjs
Normal file
@ -0,0 +1,38 @@
|
||||
/** @type {import("snowpack").SnowpackUserConfig } */
|
||||
export default {
|
||||
workspaceRoot: '..',
|
||||
mount: {
|
||||
public: { url: '/', static: false },
|
||||
src: { url: '/dist' },
|
||||
},
|
||||
plugins: [
|
||||
'@snowpack/plugin-postcss',
|
||||
'@snowpack/plugin-react-refresh',
|
||||
'@snowpack/plugin-dotenv',
|
||||
[
|
||||
'@snowpack/plugin-typescript',
|
||||
{
|
||||
/* Yarn PnP workaround: see https://www.npmjs.com/package/@snowpack/plugin-typescript */
|
||||
...(process.versions.pnp ? { tsc: 'yarn pnpify tsc' } : {}),
|
||||
},
|
||||
],
|
||||
],
|
||||
routes: [
|
||||
/* Enable an SPA Fallback in development: */
|
||||
// {"match": "routes", "src": ".*", "dest": "/index.html"},
|
||||
],
|
||||
optimize: {
|
||||
/* Example: Bundle your final build: */
|
||||
// "bundle": true,
|
||||
},
|
||||
packageOptions: {
|
||||
/* ... */
|
||||
knownEntrypoints: ['fraction.js'],
|
||||
},
|
||||
devOptions: {
|
||||
tailwindConfig: './tailwind.config.js',
|
||||
},
|
||||
buildOptions: {
|
||||
/* ... */
|
||||
},
|
||||
};
|
||||
71
repl/src/App.tsx
Normal file
71
repl/src/App.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import * as strudel from '../../strudel.mjs';
|
||||
import cx from './cx';
|
||||
|
||||
const { Fraction, TimeSpan } = strudel;
|
||||
|
||||
const fr = (v: number) => new Fraction(v);
|
||||
const ts = (start: number, end: number) => new TimeSpan(fr(start), fr(end));
|
||||
const parse = (code: string): Pattern<any> => {
|
||||
const { sequence, stack, pure } = strudel; // make available to eval
|
||||
return eval(code);
|
||||
};
|
||||
function App() {
|
||||
const [code, setCode] = useState<string>("sequence('a', 'b', sequence('c', 'd'))");
|
||||
const [events, setEvents] = useState<Hap<any>[]>([]);
|
||||
const [error, setError] = useState<Error>();
|
||||
useEffect(() => {
|
||||
try {
|
||||
const pattern = parse(code);
|
||||
console.log('pattern', pattern);
|
||||
setEvents(pattern.query(ts(0, 1)));
|
||||
console.log('events', events);
|
||||
setError(undefined);
|
||||
} catch (err: any) {
|
||||
setError(err);
|
||||
}
|
||||
}, [code]);
|
||||
return (
|
||||
<div className="h-[100vh] bg-slate-900 flex-row">
|
||||
<header className="px-2 flex items-center space-x-2 border-b border-gray-200 bg-white">
|
||||
<img src={logo} className="Tidal-logo w-16 h-16" alt="logo" />
|
||||
<h1 className="text-2xl">Strudel REPL</h1>
|
||||
</header>
|
||||
<section className="grow p-2 text-gray-100">
|
||||
<div className="relative">
|
||||
<div className="absolute right-2 bottom-2 text-red-500">{error?.message}</div>
|
||||
<textarea
|
||||
className={cx('w-full h-32 bg-slate-600', error ? 'focus:ring-red-500' : 'focus:ring-slate-800')}
|
||||
value={code}
|
||||
onChange={(e) => setCode(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<textarea className="w-full h-64 bg-slate-600" value={events.map((e) => e.show()).join('\n')} readOnly />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
declare interface Fraction {
|
||||
(v: number): Fraction;
|
||||
d: number;
|
||||
n: number;
|
||||
s: number;
|
||||
}
|
||||
declare interface TimeSpan {
|
||||
constructor: any; //?
|
||||
begin: Fraction;
|
||||
end: Fraction;
|
||||
}
|
||||
declare interface Hap<T> {
|
||||
whole: TimeSpan;
|
||||
part: TimeSpan;
|
||||
value: T;
|
||||
show: () => string;
|
||||
}
|
||||
declare interface Pattern<T> {
|
||||
query: (span: TimeSpan) => Hap<T>[];
|
||||
}
|
||||
3
repl/src/cx.ts
Normal file
3
repl/src/cx.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default function cx(...classes: Array<string | undefined>) {
|
||||
return classes.filter(Boolean).join(' ');
|
||||
}
|
||||
16
repl/src/index.tsx
Normal file
16
repl/src/index.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
||||
// Hot Module Replacement (HMR) - Remove this snippet to remove HMR.
|
||||
// Learn more: https://snowpack.dev/concepts/hot-module-replacement
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept();
|
||||
}
|
||||
33
repl/src/logo.svg
Normal file
33
repl/src/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 42 KiB |
8
repl/tailwind.config.js
Normal file
8
repl/tailwind.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
content: ['./public/**/*.html', './src/**/*.{js,jsx,ts,tsx}'],
|
||||
// specify other options here
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require('@tailwindcss/forms')],
|
||||
};
|
||||
28
repl/tsconfig.json
Normal file
28
repl/tsconfig.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"include": ["src", "types"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"baseUrl": "./",
|
||||
/* paths - import rewriting/resolving */
|
||||
"paths": {
|
||||
// If you configured any Snowpack aliases, add them here.
|
||||
// Add this line to get types for streaming imports (packageOptions.source="remote"):
|
||||
// "*": [".snowpack/types/*"]
|
||||
// More info: https://www.snowpack.dev/guides/streaming-imports
|
||||
},
|
||||
/* noEmit - Snowpack builds (emits) files, not tsc. */
|
||||
"noEmit": true,
|
||||
/* Additional Options */
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["mocha", "snowpack-env"],
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"importsNotUsedAsValues": "error"
|
||||
}
|
||||
}
|
||||
59
repl/types/static.d.ts
vendored
Normal file
59
repl/types/static.d.ts
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/* Use this file to declare any custom file extensions for importing */
|
||||
/* Use this folder to also add/extend a package d.ts file, if needed. */
|
||||
|
||||
/* CSS MODULES */
|
||||
declare module '*.module.css' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
declare module '*.module.scss' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
declare module '*.module.sass' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
declare module '*.module.less' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
declare module '*.module.styl' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
/* CSS */
|
||||
declare module '*.css';
|
||||
declare module '*.scss';
|
||||
declare module '*.sass';
|
||||
declare module '*.less';
|
||||
declare module '*.styl';
|
||||
|
||||
/* IMAGES */
|
||||
declare module '*.svg' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
declare module '*.bmp' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
declare module '*.gif' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
declare module '*.jpg' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
declare module '*.jpeg' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
declare module '*.png' {
|
||||
const ref: string;
|
||||
export default ref;
|
||||
}
|
||||
|
||||
/* CUSTOM: ADD YOUR OWN HERE */
|
||||
Loading…
x
Reference in New Issue
Block a user