mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
Merge pull request #305 from tidalcycles/estlint-prettier-check
add lint + prettier check before test
This commit is contained in:
commit
03450c6085
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
@ -10,10 +10,12 @@ jobs:
|
||||
node-version: [18]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: "npm"
|
||||
- run: npm install
|
||||
- run: npm run format-check
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
|
||||
@ -5,3 +5,4 @@
|
||||
**/out
|
||||
**/dist
|
||||
packages/mini/krill-parser.js
|
||||
packages/xen/tunejs.js
|
||||
|
||||
29
.prettierrc
29
.prettierrc
@ -1,16 +1,15 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
||||
"printWidth": 120,
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"description": "Port of tidalcycles to javascript",
|
||||
"scripts": {
|
||||
"pretest": "cd tutorial && npm run jsdoc-json",
|
||||
"test": "npm run lint && vitest run --version",
|
||||
"test": "vitest run --version",
|
||||
"test-ui": "vitest --ui",
|
||||
"test-coverage": "vitest --coverage",
|
||||
"bootstrap": "lerna bootstrap",
|
||||
@ -18,8 +18,10 @@
|
||||
"deploy": "NODE_DEBUG=gh-pages gh-pages -d out",
|
||||
"jsdoc": "jsdoc packages/ -c jsdoc.config.json",
|
||||
"jsdoc-json": "jsdoc packages/ --template ./node_modules/jsdoc-json --destination doc.json -c jsdoc.config.json",
|
||||
"lint": "npx eslint . --ext mjs,js --quiet",
|
||||
"codeformat": "prettier --write ."
|
||||
"lint": "eslint . --ext mjs,js --quiet",
|
||||
"codeformat": "prettier --write .",
|
||||
"format-check": "prettier --check .",
|
||||
"check": "npm run format-check && npm run lint && npm run test"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
||||
@ -16,7 +16,7 @@ evalScope(
|
||||
import('@strudel.cycles/tonal'),
|
||||
);
|
||||
|
||||
setStringParser(mini)
|
||||
setStringParser(mini);
|
||||
|
||||
const { evaluate } = repl({
|
||||
defaultOutput: webaudioOutput,
|
||||
|
||||
@ -80,16 +80,16 @@ export class Hap {
|
||||
}
|
||||
|
||||
show(compact = false) {
|
||||
const value = typeof this.value === 'object'
|
||||
? compact
|
||||
const value =
|
||||
typeof this.value === 'object'
|
||||
? compact
|
||||
? JSON.stringify(this.value).slice(1, -1).replaceAll('"', '').replaceAll(',', ' ')
|
||||
: JSON.stringify(this.value)
|
||||
: this.value
|
||||
: this.value;
|
||||
var spans = '';
|
||||
if (this.whole == undefined) {
|
||||
spans = '~' + this.part.show;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var is_whole = this.whole.begin.equals(this.part.begin) && this.whole.end.equals(this.part.end);
|
||||
if (!this.whole.begin.equals(this.part.begin)) {
|
||||
spans = this.whole.begin.show() + ' ⇜ ';
|
||||
@ -102,12 +102,10 @@ export class Hap {
|
||||
spans += ')';
|
||||
}
|
||||
if (!this.whole.end.equals(this.part.end)) {
|
||||
spans += ' ⇝ ' + this.whole.end.show()
|
||||
spans += ' ⇝ ' + this.whole.end.show();
|
||||
}
|
||||
}
|
||||
return (
|
||||
'[ ' + spans + ' | ' + value + ' ]'
|
||||
);
|
||||
return '[ ' + spans + ' | ' + value + ' ]';
|
||||
}
|
||||
|
||||
showWhole(compact = false) {
|
||||
|
||||
@ -541,35 +541,34 @@ export class Pattern {
|
||||
defragmentHaps() {
|
||||
// remove continuous haps
|
||||
const pat = this.discreteOnly();
|
||||
|
||||
|
||||
return pat.withHaps((haps) => {
|
||||
const result = [];
|
||||
for (var i=0; i < haps.length; ++i) {
|
||||
for (var i = 0; i < haps.length; ++i) {
|
||||
var searching = true;
|
||||
var a = haps[i];
|
||||
while (searching) {
|
||||
const a_value = JSON.stringify(haps[i].value);
|
||||
var found = false;
|
||||
|
||||
for(var j=i+1; j<haps.length; j++) {
|
||||
for (var j = i + 1; j < haps.length; j++) {
|
||||
const b = haps[j];
|
||||
|
||||
if (a.whole.equals(b.whole)) {
|
||||
if (a.part.begin.eq(b.part.end)) {
|
||||
if (a_value === JSON.stringify(b.value)) {
|
||||
// eat the matching hap into 'a'
|
||||
a = new Hap(a.whole, new TimeSpan(b.part.begin, a.part.end), a.value)
|
||||
haps.splice(j,1);
|
||||
a = new Hap(a.whole, new TimeSpan(b.part.begin, a.part.end), a.value);
|
||||
haps.splice(j, 1);
|
||||
// restart the search
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (b.part.begin.eq(a.part.end)) {
|
||||
} else if (b.part.begin.eq(a.part.end)) {
|
||||
if (a_value == JSON.stringify(b.value)) {
|
||||
// eat the matching hap into 'a'
|
||||
a = new Hap(a.whole, new TimeSpan(a.part.begin, b.part.end), a.value)
|
||||
haps.splice(j,1);
|
||||
a = new Hap(a.whole, new TimeSpan(a.part.begin, b.part.end), a.value);
|
||||
haps.splice(j, 1);
|
||||
// restart the search
|
||||
found = true;
|
||||
break;
|
||||
@ -577,7 +576,7 @@ export class Pattern {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
searching = found;
|
||||
}
|
||||
result.push(a);
|
||||
|
||||
@ -917,20 +917,18 @@ describe('Pattern', () => {
|
||||
});
|
||||
describe('defragmentHaps', () => {
|
||||
it('Can merge two touching haps with same whole and value', () => {
|
||||
expect(stack(pure('a').mask(1,0), pure('a').mask(0,1)).defragmentHaps().firstCycle().length)
|
||||
.toStrictEqual(1);
|
||||
expect(stack(pure('a').mask(1, 0), pure('a').mask(0, 1)).defragmentHaps().firstCycle().length).toStrictEqual(1);
|
||||
});
|
||||
it('Doesnt merge two overlapping haps', () => {
|
||||
expect(stack(pure('a').mask(1,1,0), pure('a').mask(0,1)).defragmentHaps().firstCycle().length)
|
||||
.toStrictEqual(2);
|
||||
expect(stack(pure('a').mask(1, 1, 0), pure('a').mask(0, 1)).defragmentHaps().firstCycle().length).toStrictEqual(
|
||||
2,
|
||||
);
|
||||
});
|
||||
it('Doesnt merge two touching haps with different values', () => {
|
||||
expect(stack(pure('a').mask(1,0), pure('b').mask(0,1)).defragmentHaps().firstCycle().length)
|
||||
.toStrictEqual(2);
|
||||
expect(stack(pure('a').mask(1, 0), pure('b').mask(0, 1)).defragmentHaps().firstCycle().length).toStrictEqual(2);
|
||||
});
|
||||
it('Doesnt merge two touching haps with different wholes', () => {
|
||||
expect(stack(sequence('a', silence), pure('a').mask(0,1)).defragmentHaps().firstCycle().length)
|
||||
.toStrictEqual(2);
|
||||
expect(stack(sequence('a', silence), pure('a').mask(0, 1)).defragmentHaps().firstCycle().length).toStrictEqual(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -20,9 +20,9 @@ export class TimeSpan {
|
||||
|
||||
// Support zero-width timespans
|
||||
if (begin.equals(end)) {
|
||||
return([new TimeSpan(begin, end)]);
|
||||
return [new TimeSpan(begin, end)];
|
||||
}
|
||||
|
||||
|
||||
while (end.gt(begin)) {
|
||||
// If begin and end are in the same cycle, we're done.
|
||||
if (begin.sam().equals(end_sam)) {
|
||||
|
||||
@ -25,8 +25,6 @@ const config = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
const osc = new OSC({ plugin: new OSC.BridgePlugin(config) });
|
||||
|
||||
osc.open(); // start a WebSocket server on port 8080
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()]
|
||||
})
|
||||
plugins: [react()],
|
||||
});
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" /> -->
|
||||
<!-- <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" /> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Strudel React Components</title>
|
||||
</head>
|
||||
|
||||
@ -9,4 +9,4 @@ module.exports = {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root'))
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
||||
@ -23,17 +23,16 @@ export async function getWriter(br = 38400) {
|
||||
const encoder = new TextEncoder();
|
||||
const writer = port.writable.getWriter();
|
||||
writeMessage = function (message, chk) {
|
||||
const encoded = encoder.encode(message)
|
||||
const encoded = encoder.encode(message);
|
||||
if (!chk) {
|
||||
writer.write(encoded);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const bytes = new Uint8Array(4);
|
||||
bytes[0] = 124; // | symbol
|
||||
bytes[1] = (chk >> 8) & 0xFF;
|
||||
bytes[2] = chk & 0xFF;
|
||||
bytes[1] = (chk >> 8) & 0xff;
|
||||
bytes[2] = chk & 0xff;
|
||||
bytes[3] = 59; // semicolon
|
||||
const withchk = new Uint8Array(encoded.length+4)
|
||||
const withchk = new Uint8Array(encoded.length + 4);
|
||||
withchk.set(encoded);
|
||||
withchk.set(bytes, encoded.length);
|
||||
writer.write(withchk);
|
||||
@ -48,12 +47,12 @@ const latency = 0.1;
|
||||
|
||||
// crc16 (CCITT-FALSE) https://gist.github.com/tijnkooijmans/10981093
|
||||
function crc16(data) {
|
||||
const length = data.length
|
||||
const length = data.length;
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var crc = 0xFFFF;
|
||||
var crc = 0xffff;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
crc ^= data.charCodeAt(i) << 8;
|
||||
for (var j = 0; j < 8; ++j) {
|
||||
@ -64,7 +63,7 @@ function crc16(data) {
|
||||
return crc & 0xffff;
|
||||
}
|
||||
|
||||
Pattern.prototype.serial = function (br=38400,sendcrc=false,singlecharids=false) {
|
||||
Pattern.prototype.serial = function (br = 38400, sendcrc = false, singlecharids = false) {
|
||||
return this.withHap((hap) => {
|
||||
if (!writeMessage) {
|
||||
getWriter(br);
|
||||
@ -96,7 +95,7 @@ Pattern.prototype.serial = function (br=38400,sendcrc=false,singlecharids=false)
|
||||
}
|
||||
message += ')';
|
||||
if (sendcrc) {
|
||||
chk = crc16(message)
|
||||
chk = crc16(message);
|
||||
}
|
||||
} else {
|
||||
for (const [key, val] of Object.entries(hap.value)) {
|
||||
@ -108,7 +107,9 @@ Pattern.prototype.serial = function (br=38400,sendcrc=false,singlecharids=false)
|
||||
}
|
||||
const offset = (time - currentTime + latency) * 1000;
|
||||
|
||||
window.setTimeout(function () {writeMessage(message, chk)}, offset);
|
||||
window.setTimeout(function () {
|
||||
writeMessage(message, chk);
|
||||
}, offset);
|
||||
};
|
||||
return hap.setContext({ ...hap.context, onTrigger, dominantTrigger: true });
|
||||
});
|
||||
|
||||
@ -42,7 +42,7 @@ export const instruments = [
|
||||
'0031_FluidR3_GM_sf2_file',
|
||||
'0031_GeneralUserGS_sf2_file',
|
||||
'0031_SoundBlasterOld_sf2', // pianos until here
|
||||
'0040_Aspirin_sf2_file',
|
||||
'0040_Aspirin_sf2_file',
|
||||
'0040_Chaos_sf2_file',
|
||||
'0040_FluidR3_GM_sf2_file', // rhodes
|
||||
'0040_GeneralUserGS_sf2_file', // staccato rhodes
|
||||
@ -59,7 +59,7 @@ export const instruments = [
|
||||
'0046_GeneralUserGS_sf2_file', // ?
|
||||
'0050_Aspirin_sf2_file', // glass organ
|
||||
'0050_Chaos_sf2_file', // short glass organ
|
||||
'0050_FluidR3_GM_sf2_file',// long glass organ !
|
||||
'0050_FluidR3_GM_sf2_file', // long glass organ !
|
||||
'0050_GeneralUserGS_sf2_file', // short glass organ
|
||||
'0050_JCLive_sf2_file', // glass organ
|
||||
'0050_SBLive_sf2', // ?
|
||||
@ -1635,7 +1635,7 @@ export const drums = [
|
||||
'81_4_Chaos_sf2_file',
|
||||
];
|
||||
|
||||
// see https://www.midi.org/specifications-old/item/gm-level-1-sound-set
|
||||
// see https://www.midi.org/specifications-old/item/gm-level-1-sound-set
|
||||
export const instrumentNames = [];
|
||||
instrumentNames[0] = 'Acoustic Grand Piano: Piano';
|
||||
instrumentNames[1] = 'Bright Acoustic Piano: Piano';
|
||||
|
||||
@ -9,4 +9,4 @@ module.exports = {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
|
||||
'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
@ -9,4 +9,4 @@ module.exports = {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user