diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 8ef7ca6..e19771f 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -1,12 +1,11 @@
/* eslint-env node */
-module.exports =
-{
+module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
+ 'standard-with-typescript',
'plugin:@typescript-eslint/recommended',
- 'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:react-hooks/recommended',
'plugin:react/recommended',
'prettier',
@@ -48,5 +47,5 @@ module.exports =
},
],
},
-}
+};
diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml
new file mode 100644
index 0000000..0a47103
--- /dev/null
+++ b/.github/workflows/eslint.yml
@@ -0,0 +1,60 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# ESLint is a tool for identifying and reporting on patterns
+# found in ECMAScript/JavaScript code.
+# More details at https://github.com/eslint/eslint
+# and https://eslint.org
+
+name: ESLint
+
+on:
+ push:
+ branches: ['main']
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: ['main']
+ schedule:
+ - cron: '16 20 * * 0'
+
+jobs:
+ eslint:
+ name: Run eslint scanning
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ security-events: write
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Install ESLint formatter
+ run: |
+ npm install @microsoft/eslint-formatter-sarif@2.1.7
+
+ - name: Run ESLint
+ run: npx eslint src
+ --report-unused-disable-directives
+ --max-warnings 0
+ --config .eslintrc.cjs
+ --ext .js,.jsx,.ts,.tsx
+ --format @microsoft/eslint-formatter-sarif
+ --output-file eslint-results.sarif
+ continue-on-error: true
+
+ - name: Upload analysis results to GitHub
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: eslint-results.sarif
+ wait-for-processing: true
diff --git a/modelverify.html b/modelverify.html
deleted file mode 100644
index 12566e7..0000000
--- a/modelverify.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- CFlowSim: Physics in the Browser for the People
-
-
-
-
-
-
-
-
-
diff --git a/src/App.tsx b/src/App.tsx
index aa38b74..a1a55a8 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,3 +1,4 @@
+import type React from 'react';
import { useEffect, useState } from 'react';
import NavBar from './components/NavBar';
import styled, { ThemeProvider } from 'styled-components';
@@ -6,7 +7,7 @@ import './App.css';
import Home from './pages';
import AboutPage from './pages/about';
import { SimulationParams } from './components/Simulation';
-import { IncomingMessage } from './workers/modelWorkerMessage';
+import { type IncomingMessage } from './workers/modelWorkerMessage';
const Main = styled.main`
position: absolute;
@@ -14,7 +15,7 @@ const Main = styled.main`
top: 0;
width: 100vw;
height: 100vh;
- background: ${(props) => (props.theme.light ? '#ffffff' : '#707070')};
+ background: ${(props) => ((props.theme.light as boolean) ? '#ffffff' : '#707070')};
z-index: 0;
`;
@@ -25,7 +26,7 @@ const NavBarContainer = styled.div`
font-family: 'Titillium Web', sans-serif;
`;
-function App() {
+function App(): React.ReactElement {
// save the current page in state
// 0 = home(index,simulation) 1 = about
const [page, setPage] = useState(0);
@@ -35,7 +36,6 @@ function App() {
const [lightTheme, setlightTheme] = useState(false);
// TODO: implement auto theme ui switch
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
const [curThemeMode, setCurThemeMode] = useState('auto'); // 'dark' or 'light' or 'auto'
useEffect(() => {
@@ -62,9 +62,10 @@ function App() {
},
);
setSimWorker(worker);
- worker.postMessage({
+ const message: IncomingMessage = {
func: 'init',
- } as IncomingMessage);
+ };
+ worker.postMessage(message);
}, []);
let mainPageComponent;
diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx
index e109e6b..0c7ec85 100644
--- a/src/components/NavBar.tsx
+++ b/src/components/NavBar.tsx
@@ -13,8 +13,8 @@ const Header = styled.header`
display: flex;
align-items: center;
height: 5rem;
- background-color: ${(props) => (props.theme.light ? '#004b87' : '#142c3f')};
- color: ${(props) => (props.theme.light ? '#f5f5f5' : '#9faee5')};
+ background-color: ${(props) => (props.theme.light as boolean ? '#004b87' : '#142c3f')};
+ color: ${(props) => (props.theme.light as boolean ? '#f5f5f5' : '#9faee5')};
`;
const LogoAnchor = styled.a`
@@ -132,10 +132,10 @@ export default function NavBar(props: NavBarProps): React.ReactElement {
- setPage(0)}>
+ { setPage(0); }}>
Simulations
- setPage(1)}>
+ { setPage(1); }}>
About
{isShowExtend ? (
- setPage(0)}>
+ { setPage(0); }}>
Simulations
- setPage(1)}>
+ { setPage(1); }}>
About
{
- void (() => {
+ (() => {
worker.onmessage = (e) => {
const data = e.data as OutgoingMessage;
@@ -141,7 +141,6 @@ function DiffusionPlane(
})();
// SUBSCRIPTIONS
-
// update the density uniforms every time
// output is received
function output(data: Float32Array): void {
diff --git a/src/pages/about.tsx b/src/pages/about.tsx
index c3fbbca..cf1daa7 100644
--- a/src/pages/about.tsx
+++ b/src/pages/about.tsx
@@ -8,7 +8,7 @@ const Content = styled.div`
margin-top: 4%;
margin-bottom: 8%;
font-family: 'Roboto', sans-serif;
- color: ${(props) => (props.theme.light ? '#333333' : '#c9c9c9' )};
+ color: ${(props) => (props.theme.light as boolean ? '#333333' : '#c9c9c9' )};
a:link {
text-decoration: none;
}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 6426f2a..2a1ef39 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,6 +1,6 @@
import ParBar from '../components/ParametersBar';
import ControlBar from '../components/ControlBar';
-import { DiffusionPlane, SimulationParams } from '../components/Simulation';
+import { DiffusionPlane, type SimulationParams } from '../components/Simulation';
import { Canvas } from '@react-three/fiber';
import styled from 'styled-components';
diff --git a/src/pages/modelverify.tsx b/src/pages/modelverify.tsx
deleted file mode 100644
index ad75b64..0000000
--- a/src/pages/modelverify.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-unsafe-argument */
-/* eslint-disable @typescript-eslint/no-unsafe-return */
-/* eslint-disable @typescript-eslint/no-unsafe-call */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-import { useEffect, useState } from 'react';
-
-export default function Home(): React.ReactElement {
- const [paused, setPaused] = useState(true);
- const [worker, setWorker] = useState(null);
- useEffect(() => {
- void (() => {
- const worker = new Worker(
- new URL('../workers/modelWorker', import.meta.url),
- {
- type: 'module',
- },
- );
- console.log('worker created', worker);
- worker.postMessage({ func: 'init' });
- worker.onmessage = (e: MessageEvent) => {
- if (e.data.type === 'output') {
- const density = e.data.density;
- // log the array 64x64
- // chunk the array into 64x64
- const chunked = [];
- for (let i = 0; i < density.length; i += 64) {
- chunked.push(density.slice(i, i + 64));
- }
- console.log(chunked);
- // log some values
- console.log(
- 'average density',
- density.reduce((a: any, b: any) => a + b) / density.length,
- );
- console.log('max density', Math.max(...density));
- console.log('min density', Math.min(...density));
- console.log(
- 'density std dev',
- Math.sqrt(
- density.reduce((a: any, b: any) => a + b * b) / density.length -
- Math.pow(
- density.reduce((a: any, b: any) => a + b) / density.length,
- 2,
- ),
- ),
- );
- } else console.log(e.data);
- };
- worker.onerror = (e) => {
- console.log(e);
- };
- setWorker(worker);
- console.log('worker created');
- })();
- }, []);
-
- return (
- // write a simple article to guide user to console
- <>
-
- Model Verification
-
-
-
-
-
- Model Verification
- This page is used to verify the model. See console for output.
-
-
- >
- );
-}
diff --git a/src/pages/wip-simDraft b/src/pages/wip-simDraft
deleted file mode 100644
index f59c6f8..0000000
--- a/src/pages/wip-simDraft
+++ /dev/null
@@ -1,51 +0,0 @@
-import css from '../styles/Home.module.css';
-import { Canvas } from '@react-three/fiber';
-import { MapControls, Stats } from '@react-three/drei';
-import { DiffusionPlane, SimulationParams } from '../components/Simulation';
-import { Color } from 'three';
-import { useEffect, useState } from 'react';
-
-export default function Home(): React.ReactElement {
- const [enableMapControls, setEnableMapControls] = useState(false);
- useEffect(() => {
- (window as any).testMapControlsToggle = setEnableMapControls;
- }, []);
-
- const params: SimulationParams = new SimulationParams();
- params.densityLowColour = new Color('green');
-
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const [worker, setWorker] = useState(null!);
-
- useEffect(() => {
- const worker = new Worker(
- new URL('../workers/modelWorker', import.meta.url),
- {
- type: 'module',
- },
- );
- setWorker(worker);
- }, []);
-
- return (
-
- );
-}
diff --git a/src/services/model/ONNXService.ts b/src/services/model/ONNXService.ts
index d5c26a3..e70744b 100644
--- a/src/services/model/ONNXService.ts
+++ b/src/services/model/ONNXService.ts
@@ -375,6 +375,7 @@ export default class ONNXService implements ModelService {
private roundFloat(value: number, decimal = 4): number {
return Math.round(value * 10 ** decimal) / 10 ** decimal;
}
+
getInputTensor(): Float32Array {
return this.matrixArray;
}
diff --git a/src/services/model/TfjsService.ts b/src/services/model/TfjsService.ts
index 12bbb0d..cb5c333 100644
--- a/src/services/model/TfjsService.ts
+++ b/src/services/model/TfjsService.ts
@@ -136,12 +136,14 @@ export class TfjsService implements ModelService {
}
}, 1000);
}
+
getInput(): tf.Tensor {
const pressure = this.pressure.toTensor();
const input = tf.concat([this.density, this.velocity, pressure], 3);
pressure.dispose();
return input;
}
+
private iterate(): void {
if (this.isPaused) {
return;
@@ -204,12 +206,14 @@ export class TfjsService implements ModelService {
4,
);
}
+
getInputTensor(): Float32Array {
const input = this.getInput();
const data = input.dataSync();
input.dispose();
return data as Float32Array;
}
+
dispose(): void {
this.density.dispose();
this.velocity.dispose();
diff --git a/src/services/model/modelService.ts b/src/services/model/modelService.ts
index 8da185a..35e75e6 100644
--- a/src/services/model/modelService.ts
+++ b/src/services/model/modelService.ts
@@ -25,7 +25,7 @@ export async function createModelService(
const modelType = modelPath.split('.').pop();
switch (modelType) {
case 'json':
- return TfjsService.createService(
+ return await TfjsService.createService(
modelPath,
gridSize,
batchSize,
@@ -34,7 +34,7 @@ export async function createModelService(
fpsLimit,
);
case 'onnx':
- return ONNXService.createService(
+ return await ONNXService.createService(
modelPath,
gridSize,
batchSize,
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 11f02fe..e578524 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1 +1,2 @@
+// eslint-disable-next-line @typescript-eslint/triple-slash-reference
///
diff --git a/src/workers/modelWorker.ts b/src/workers/modelWorker.ts
index 9daf10c..d75e437 100644
--- a/src/workers/modelWorker.ts
+++ b/src/workers/modelWorker.ts
@@ -1,11 +1,11 @@
// a worker that can control the modelService via messages
-import { Vector2 } from 'three';
+import { type Vector2 } from 'three';
import {
- ModelService,
+ type ModelService,
createModelService,
} from '../services/model/modelService';
-import { IncomingMessage } from './modelWorkerMessage';
+import { type IncomingMessage } from './modelWorkerMessage';
let modelService: ModelService | null = null;
@@ -67,7 +67,7 @@ export function onmessage(
throw new Error(`unknown func ${data.func}`);
}
}
-function updateForce(args: UpdateForceArgs) {
+function updateForce(args: UpdateForceArgs): void {
if (modelService == null) {
throw new Error('modelService is null');
}
@@ -94,8 +94,8 @@ async function initModelService(
const modelService = await createModelService(modelPath, [64, 64], 1);
modelService.bindOutput(outputCallback);
// fetch the data
- const data = (await fetch(dataPath).then((res) =>
- res.json(),
+ const data = (await fetch(dataPath).then(async (res) =>
+ await res.json(),
)) as number[][][][];
modelService.loadDataArray(data);
return modelService;