An easy-to-use platform for EEG experimentation in the classroom
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

eslint

+193 -223
-60
.eslintignore
··· 1 - # Logs 2 - logs 3 - *.log 4 - 5 - # Runtime data 6 - pids 7 - *.pid 8 - *.seed 9 - 10 - # Directory for instrumented libs generated by jscoverage/JSCover 11 - lib-cov 12 - 13 - # Coverage directory used by tools like istanbul 14 - coverage 15 - 16 - # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 - .grunt 18 - 19 - # node-waf configuration 20 - .lock-wscript 21 - 22 - # Compiled binary addons (http://nodejs.org/api/addons.html) 23 - build/Release 24 - .eslintcache 25 - 26 - # Dependency directory 27 - # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 28 - node_modules 29 - app/node_modules 30 - 31 - # OSX 32 - .DS_Store 33 - 34 - # Build outputs 35 - release 36 - out 37 - dist 38 - dll 39 - 40 - # Old webpack build artifacts 41 - app/*.main.prod.js 42 - app/main.prod.js 43 - app/main.prod.js.map 44 - app/renderer.prod.js 45 - app/renderer.prod.js.map 46 - app/style.css 47 - app/style.css.map 48 - main.js 49 - main.js.map 50 - 51 - .idea 52 - npm-debug.log.* 53 - __snapshots__ 54 - 55 - # Package.json 56 - package.json 57 - .travis.yml 58 - *.css.d.ts 59 - *.sass.d.ts 60 - *.scss.d.ts
-52
.eslintrc.js
··· 1 - module.exports = { 2 - extends: 'erb/typescript', 3 - rules: { 4 - '@typescript-eslint/ban-ts-comment': 'warn', 5 - '@typescript-eslint/no-use-before-define': 'off', 6 - '@typescript-eslint/naming-convention': 'off', 7 - 'consistent-return': 'warn', 8 - 'dot-notation': 'off', 9 - 'import/no-extraneous-dependencies': 'off', 10 - 'import/prefer-default-export': 'off', 11 - 'import/no-cycle': 'warn', 12 - 'jsx-a11y/anchor-is-valid': 'warn', 13 - 'jsx-a11y/click-events-have-key-events': 'warn', 14 - 'lines-between-class-members': 'off', 15 - 'max-classes-per-file': 'off', 16 - 'no-param-reassign': 'off', 17 - 'no-plusplus': 'off', 18 - 'no-restricted-syntax': 'off', 19 - 'prefer-destructuring': 'warn', 20 - 'promise/no-return-wrap': 'warn', 21 - 'react/destructuring-assignment': 'off', 22 - 'react/jsx-curly-newline': 'off', 23 - 'react/jsx-one-expression-per-line': 'off', 24 - 'react/jsx-props-no-spreading': 'off', 25 - 'react/jsx-wrap-multilines': 'off', 26 - 'react/no-access-state-in-setstate': 'warn', 27 - 'react/no-array-index-key': 'off', 28 - 'react/no-did-update-set-state': 'warn', 29 - 'react/no-will-update-set-state': 'warn', 30 - 'react/prop-types': 'off', 31 - 'react/static-property-placement': 'off', 32 - }, 33 - parserOptions: { 34 - ecmaVersion: 2020, 35 - sourceType: 'module', 36 - project: './tsconfig.json', 37 - tsconfigRootDir: __dirname, 38 - createDefaultProgram: true, 39 - }, 40 - settings: { 41 - 'import/resolver': { 42 - // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below 43 - node: {}, 44 - webpack: { 45 - config: require.resolve('./configs/webpack.config.eslint.js'), 46 - }, 47 - }, 48 - 'import/parsers': { 49 - '@typescript-eslint/parser': ['.ts', '.tsx'], 50 - }, 51 - }, 52 - };
+174
eslint.config.mjs
··· 1 + import js from '@eslint/js'; 2 + import tsPlugin from '@typescript-eslint/eslint-plugin'; 3 + import tsParser from '@typescript-eslint/parser'; 4 + import reactPlugin from 'eslint-plugin-react'; 5 + import reactHooksPlugin from 'eslint-plugin-react-hooks'; 6 + import importPlugin from 'eslint-plugin-import'; 7 + import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'; 8 + import prettierPlugin from 'eslint-plugin-prettier'; 9 + import prettierConfig from 'eslint-config-prettier'; 10 + import globals from 'globals'; 11 + import { fileURLToPath } from 'url'; 12 + import { dirname } from 'path'; 13 + 14 + const __dirname = dirname(fileURLToPath(import.meta.url)); 15 + 16 + export default [ 17 + // --- Global ignores (replaces .eslintignore) --- 18 + { 19 + ignores: [ 20 + 'node_modules/**', 21 + 'out/**', 22 + 'release/**', 23 + 'dist/**', 24 + 'coverage/**', 25 + 'src/renderer/utils/pyodide/src/**', 26 + '**/*.css.d.ts', 27 + '**/*.scss.d.ts', 28 + ], 29 + }, 30 + 31 + // --- Base JS recommended rules --- 32 + js.configs.recommended, 33 + 34 + // --- TypeScript-eslint flat/recommended (array of 3 config objects) --- 35 + // Sets up @typescript-eslint parser + plugin globally and TS-specific rules. 36 + ...tsPlugin.configs['flat/recommended'], 37 + 38 + // --- React flat recommended --- 39 + { 40 + ...reactPlugin.configs.flat.recommended, 41 + settings: { react: { version: 'detect' } }, 42 + }, 43 + 44 + // --- React hooks recommended (flat config) --- 45 + reactHooksPlugin.configs['recommended-latest'], 46 + 47 + // --- TypeScript + React source files --- 48 + { 49 + files: ['src/**/*.{ts,tsx}', 'internals/**/*.ts'], 50 + languageOptions: { 51 + parser: tsParser, 52 + parserOptions: { 53 + ecmaVersion: 2020, 54 + sourceType: 'module', 55 + tsconfigRootDir: __dirname, 56 + }, 57 + globals: { 58 + ...globals.browser, 59 + ...globals.node, 60 + ...globals.es2020, 61 + }, 62 + }, 63 + plugins: { 64 + import: importPlugin, 65 + 'jsx-a11y': jsxA11yPlugin, 66 + prettier: prettierPlugin, 67 + }, 68 + settings: { 69 + react: { version: 'detect' }, 70 + 'import/parsers': { 71 + '@typescript-eslint/parser': ['.ts', '.tsx'], 72 + }, 73 + 'import/resolver': { node: {} }, 74 + }, 75 + rules: { 76 + // jsx-a11y recommended rules 77 + ...jsxA11yPlugin.configs.recommended.rules, 78 + 79 + // Prettier formatting 80 + ...prettierConfig.rules, 81 + 'prettier/prettier': 'warn', 82 + 83 + // Downgrade from error → warn for gradual adoption 84 + '@typescript-eslint/ban-ts-comment': 'warn', 85 + '@typescript-eslint/no-explicit-any': 'warn', 86 + '@typescript-eslint/no-unused-vars': 'warn', 87 + 88 + // Disabled from old config 89 + '@typescript-eslint/no-use-before-define': 'off', 90 + '@typescript-eslint/naming-convention': 'off', 91 + 'consistent-return': 'warn', 92 + 'dot-notation': 'off', 93 + 'import/no-extraneous-dependencies': 'off', 94 + 'import/prefer-default-export': 'off', 95 + 'import/no-cycle': 'warn', 96 + 'jsx-a11y/anchor-is-valid': 'warn', 97 + 'jsx-a11y/click-events-have-key-events': 'warn', 98 + 'jsx-a11y/no-autofocus': 'warn', 99 + 'react/no-unknown-property': 'warn', 100 + 'lines-between-class-members': 'off', 101 + 'max-classes-per-file': 'off', 102 + 'no-param-reassign': 'off', 103 + 'no-plusplus': 'off', 104 + 'no-restricted-syntax': 'off', 105 + 'prefer-destructuring': 'warn', 106 + 'react/destructuring-assignment': 'off', 107 + 'react/jsx-curly-newline': 'off', 108 + 'react/jsx-one-expression-per-line': 'off', 109 + 'react/jsx-props-no-spreading': 'off', 110 + 'react/jsx-wrap-multilines': 'off', 111 + 'react/no-access-state-in-setstate': 'warn', 112 + 'react/no-array-index-key': 'off', 113 + 'react/no-did-update-set-state': 'warn', 114 + 'react/no-will-update-set-state': 'warn', 115 + 'react/prop-types': 'off', 116 + 'react/static-property-placement': 'off', 117 + }, 118 + }, 119 + 120 + // --- Web Worker file — add worker globals so importScripts/self/etc. are known --- 121 + { 122 + files: ['src/**/webworker.js'], 123 + languageOptions: { 124 + globals: { 125 + ...globals.worker, 126 + ...globals.es2020, 127 + loadPyodide: 'readonly', 128 + }, 129 + }, 130 + }, 131 + 132 + // --- Plain JS/JSX source files --- 133 + { 134 + files: ['src/**/*.{js,jsx}'], 135 + languageOptions: { 136 + ecmaVersion: 2020, 137 + sourceType: 'module', 138 + globals: { 139 + ...globals.browser, 140 + ...globals.node, 141 + ...globals.es2020, 142 + }, 143 + }, 144 + plugins: { 145 + prettier: prettierPlugin, 146 + }, 147 + settings: { 148 + react: { version: 'detect' }, 149 + }, 150 + rules: { 151 + ...prettierConfig.rules, 152 + 'prettier/prettier': 'warn', 153 + '@typescript-eslint/no-unused-vars': 'warn', 154 + 'no-param-reassign': 'off', 155 + 'no-plusplus': 'off', 156 + }, 157 + }, 158 + 159 + // --- Internals scripts — Node.js, more relaxed --- 160 + { 161 + files: ['internals/**/*.{js,mjs,ts}'], 162 + languageOptions: { 163 + globals: { 164 + ...globals.node, 165 + ...globals.es2020, 166 + }, 167 + }, 168 + rules: { 169 + 'no-console': 'off', 170 + '@typescript-eslint/no-require-imports': 'off', 171 + 'import/no-extraneous-dependencies': 'off', 172 + }, 173 + }, 174 + ];
-8
internals/scripts/.eslintrc
··· 1 - { 2 - "rules": { 3 - "no-console": "off", 4 - "global-require": "off", 5 - "import/no-dynamic-require": "off", 6 - "import/no-extraneous-dependencies": "off" 7 - } 8 - }
+15 -13
package.json
··· 16 16 "package-linux": "npm run build && electron-builder build --linux", 17 17 "package-win": "npm run build && electron-builder build --win --x64", 18 18 "postinstall": "electron-builder install-app-deps && node internals/scripts/InstallPyodide.js && node internals/scripts/patchDeps.mjs", 19 - "lint": "cross-env NODE_ENV=development eslint . --cache --ext .js,.jsx,.ts,.tsx", 19 + "lint": "cross-env NODE_ENV=development eslint . --cache", 20 20 "lint-fix": "npm run lint -- --fix", 21 - "lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss", 21 + "lint-styles": "stylelint '**/*.*(css|scss)'", 22 22 "lint-styles-fix": "npm run lint-styles -- --fix; exit 0", 23 - "postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'", 24 - "postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'", 23 + "postlint-fix": "prettier --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'", 24 + "postlint-styles-fix": "prettier --single-quote --write '**/*.{css,scss}'", 25 25 "test": "cross-env jest --passWithNoTests", 26 26 "test-all": "npm run lint && npm run tsc && npm run build && npm test", 27 27 "tsc": "tsc --noEmit" ··· 30 30 "*.{js,jsx,ts,tsx}": [ 31 31 "cross-env NODE_ENV=development eslint --cache" 32 32 ], 33 - "{*.json,.{eslintrc,prettierrc,stylelintrc}}": [ 34 - "prettier --ignore-path .eslintignore --parser json --write" 33 + "{*.json,.{prettierrc,stylelintrc}}": [ 34 + "prettier --parser json --write" 35 35 ], 36 36 "*.{css,scss}": [ 37 - "stylelint --ignore-path .eslintignore --syntax scss --fix", 38 - "prettier --ignore-path .eslintignore --single-quote --write" 37 + "stylelint --fix", 38 + "prettier --single-quote --write" 39 39 ], 40 40 "*.{html,md,yml}": [ 41 - "prettier --ignore-path .eslintignore --single-quote --write" 41 + "prettier --single-quote --write" 42 42 ] 43 43 }, 44 44 "build": { ··· 135 135 ], 136 136 "homepage": "https://github.com/makebrainwaves/BrainWaves/", 137 137 "jest": { 138 - "testURL": "http://localhost/", 138 + "testEnvironment": "node", 139 + "testEnvironmentOptions": { 140 + "url": "http://localhost/" 141 + }, 139 142 "moduleNameMapper": { 140 143 "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/mocks/fileMock.js", 141 144 "\\.(css|less|sass|scss)$": "identity-obj-proxy" ··· 149 152 ], 150 153 "moduleDirectories": [ 151 154 "node_modules" 152 - ], 153 - "setupFiles": [] 155 + ] 154 156 }, 155 157 "devDependencies": { 156 158 "@babel/plugin-proposal-class-properties": "^7.10.4", 157 159 "@babel/plugin-proposal-decorators": "^7.10.5", 158 160 "@types/history": "^4.7.6", 159 - "@types/jest": "^26.0.5", 161 + "@types/jest": "^30.0.0", 160 162 "@types/node": "^22.12.0", 161 163 "@types/react": "^16.9.38", 162 164 "@types/react-dom": "^16.9.8",
+4 -1
src/renderer/constants/constants.ts
··· 51 51 52 52 export const SEARCH_TIMER = 3000; 53 53 54 - // NOTE: the actual marker id values of stimulus 1 and 2 are reversed 54 + // NOTE: TARGET/NONTARGET are intentional semantic aliases for STIMULUS_2/STIMULUS_1 55 + // because the actual marker id values of stimulus 1 and 2 are reversed. 55 56 export enum EVENTS { 56 57 STIMULUS_1 = 1, 57 58 STIMULUS_2 = 2, 58 59 STIMULUS_3 = 3, 59 60 STIMULUS_4 = 4, 61 + /* eslint-disable @typescript-eslint/no-duplicate-enum-values */ 60 62 TARGET = 2, 61 63 NONTARGET = 1, 64 + /* eslint-enable @typescript-eslint/no-duplicate-enum-values */ 62 65 } 63 66 64 67 export const CHANNELS = {
-76
src/renderer/store/configureStore.dev.js
··· 1 - import { createStore, applyMiddleware, compose } from 'redux'; 2 - import thunk from 'redux-thunk'; 3 - import { createEpicMiddleware } from 'redux-observable'; 4 - import { createHashHistory } from 'history'; 5 - import { routerMiddleware, routerActions } from 'react-router-redux'; 6 - import { createLogger } from 'redux-logger'; 7 - import rootReducer from '../reducers'; 8 - import rootEpic from '../epics'; 9 - import * as pyodideActions from '../actions/pyodideActions'; 10 - import * as deviceActions from '../actions/deviceActions'; 11 - 12 - const history = createHashHistory(); 13 - 14 - const configureStore = (initialState?: AppState) => { 15 - // Redux Configuration 16 - const middleware = []; 17 - const enhancers = []; 18 - 19 - // Thunk Middleware 20 - middleware.push(thunk); 21 - 22 - // Redux Observable (Epic) Middleware 23 - const epicMiddleware = createEpicMiddleware(); 24 - middleware.push(epicMiddleware); 25 - 26 - // Logging Middleware 27 - const logger = createLogger({ 28 - level: 'info', 29 - collapsed: true, 30 - }); 31 - 32 - // Skip redux logs in console during the tests 33 - if (import.meta.env.MODE !== 'test') { 34 - middleware.push(logger); 35 - } 36 - 37 - // Router Middleware 38 - const router = routerMiddleware(history); 39 - middleware.push(router); 40 - 41 - // Redux DevTools Configuration 42 - const actionCreators = { 43 - ...deviceActions, 44 - ...pyodideActions, 45 - ...routerActions, 46 - }; 47 - // If Redux DevTools Extension is installed use it, otherwise use Redux compose 48 - /* eslint-disable no-underscore-dangle */ 49 - const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ 50 - ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ 51 - // Options: http://zalmoxisus.github.io/redux-devtools-extension/API/Arguments.html 52 - actionCreators, 53 - }) 54 - : compose; 55 - /* eslint-enable no-underscore-dangle */ 56 - 57 - // Apply Middleware & Compose Enhancers 58 - enhancers.push(applyMiddleware(...middleware)); 59 - const enhancer = composeEnhancers(...enhancers); 60 - 61 - // Create Store 62 - const store = createStore(rootReducer, initialState, enhancer); 63 - 64 - if (import.meta.hot) { 65 - import.meta.hot.accept('../reducers', (newModule) => { 66 - store.replaceReducer(newModule?.default ?? newModule); 67 - }); 68 - } 69 - 70 - // Redux Observable 71 - epicMiddleware.run(rootEpic); 72 - 73 - return store; 74 - }; 75 - 76 - export default { configureStore, history };
-13
test/.eslintrc.json
··· 1 - { 2 - "extends": "plugin:testcafe/recommended", 3 - "env": { 4 - "jest/globals": true 5 - }, 6 - "plugins": ["jest", "testcafe"], 7 - "rules": { 8 - "jest/no-disabled-tests": "warn", 9 - "jest/no-focused-tests": "error", 10 - "jest/no-identical-title": "error", 11 - "no-console": "off" 12 - } 13 - }