mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-17 12:30:35 +08:00
Merge pull request #831 from c-bata/biome-ci-standalone-app
Use `biome ci` on `standalone_app`
This commit is contained in:
+3
-2
@@ -1,2 +1,3 @@
|
||||
venv/**/*.ts
|
||||
venv/**/*.js
|
||||
venv
|
||||
.venv
|
||||
standalone_app
|
||||
+2
-2
@@ -6,9 +6,9 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"fmt": "biome format --write .",
|
||||
"lint": "npm run lint:eslint && npm run lint:fmt",
|
||||
"lint": "npm run lint:eslint && npm run lint:biome",
|
||||
"lint:eslint": "eslint . --ext .ts,.tsx --max-warnings 0",
|
||||
"lint:fmt": "biome format .",
|
||||
"lint:biome": "biome format . && biome ci standalone_app",
|
||||
"watch": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack --watch",
|
||||
"build": "webpack",
|
||||
"build:dev": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import "./index.css"
|
||||
import { App } from "./components/App"
|
||||
import { RecoilRoot } from "recoil"
|
||||
import { App } from "./components/App"
|
||||
import "./index.css"
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, { FC, useMemo, useState, useEffect } from "react"
|
||||
import { HashRouter as Router, Routes, Route } from "react-router-dom"
|
||||
import { SnackbarProvider } from "notistack"
|
||||
import blue from "@mui/material/colors/blue"
|
||||
import pink from "@mui/material/colors/pink"
|
||||
import {
|
||||
createTheme,
|
||||
useMediaQuery,
|
||||
ThemeProvider,
|
||||
Box,
|
||||
CssBaseline,
|
||||
ThemeProvider,
|
||||
createTheme,
|
||||
useMediaQuery,
|
||||
} from "@mui/material"
|
||||
import blue from "@mui/material/colors/blue"
|
||||
import pink from "@mui/material/colors/pink"
|
||||
import { SnackbarProvider } from "notistack"
|
||||
import React, { FC, useMemo, useState, useEffect } from "react"
|
||||
import { HashRouter as Router, Route, Routes } from "react-router-dom"
|
||||
|
||||
import { StudyDetail } from "./StudyDetail"
|
||||
import { StudyList } from "./StudyList"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import React from "react"
|
||||
import { Clear } from "@mui/icons-material"
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"
|
||||
import {
|
||||
Collapse,
|
||||
IconButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
@@ -8,18 +12,14 @@ import {
|
||||
TablePagination,
|
||||
TableRow,
|
||||
TableSortLabel,
|
||||
Collapse,
|
||||
IconButton,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import { styled } from "@mui/system"
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"
|
||||
import { Clear } from "@mui/icons-material"
|
||||
import React from "react"
|
||||
|
||||
type Order = "asc" | "desc"
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
type Value = any
|
||||
|
||||
const defaultRowsPerPageOption = [10, 50, 100, { label: "All", value: -1 }]
|
||||
@@ -97,7 +97,7 @@ function DataGrid<T>(props: {
|
||||
}
|
||||
|
||||
const filteredRows = rows.filter((row, rowIdx) => {
|
||||
if (defaultFilter !== undefined && defaultFilter(row)) {
|
||||
if (defaultFilter?.(row)) {
|
||||
return false
|
||||
}
|
||||
return filters.length === 0
|
||||
@@ -162,6 +162,7 @@ function DataGrid<T>(props: {
|
||||
{collapseBody ? <TableCell /> : null}
|
||||
{columns.map((column, columnIdx) => (
|
||||
<TableCell
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
||||
key={columnIdx}
|
||||
padding={column.padding || "normal"}
|
||||
sortDirection={orderBy === column.field ? order : false}
|
||||
@@ -378,4 +379,5 @@ const isNumber = (
|
||||
return typeof rowsPerPage === "number"
|
||||
}
|
||||
|
||||
export { DataGrid, DataGridColumn }
|
||||
export { DataGrid }
|
||||
export type { DataGridColumn }
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import React, { ChangeEvent, FC, useEffect, useState } from "react"
|
||||
import {
|
||||
Grid,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
FormControlLabel,
|
||||
Checkbox,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
FormLabel,
|
||||
Grid,
|
||||
MenuItem,
|
||||
Switch,
|
||||
Select,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Typography,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
Switch,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import React, { ChangeEvent, FC, useEffect, useState } from "react"
|
||||
import { plotlyDarkTemplate } from "../PlotlyDarkMode"
|
||||
|
||||
const plotDomId = "plot-history"
|
||||
@@ -91,6 +91,7 @@ export const PlotHistory: FC<{
|
||||
<FormLabel component="legend">Objective ID:</FormLabel>
|
||||
<Select value={objectiveId} onChange={handleObjectiveChange}>
|
||||
{study.directions.map((d, i) => (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
||||
<MenuItem value={i} key={i}>
|
||||
{i}
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material"
|
||||
import init, { wasm_fanova_calculate } from "optuna"
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import React, { FC, useEffect, useState } from "react"
|
||||
import { Typography, useTheme, Box } from "@mui/material"
|
||||
import init, { wasm_fanova_calculate } from "optuna"
|
||||
|
||||
import { plotlyDarkTemplate } from "../PlotlyDarkMode"
|
||||
const plotDomId = "graph-hyperparameter-importances"
|
||||
|
||||
export const PlotImportance: FC<{ study: Study }> = ({ study }) => {
|
||||
const theme = useTheme()
|
||||
const nObjectives = study.directions.length
|
||||
const objectiveNames: string[] = study.directions.map(
|
||||
(d, i) => `Objective ${i}`
|
||||
)
|
||||
@@ -50,13 +49,13 @@ export const PlotImportance: FC<{ study: Study }> = ({ study }) => {
|
||||
}
|
||||
|
||||
run_wasm()
|
||||
}, [])
|
||||
}, [study])
|
||||
|
||||
useEffect(() => {
|
||||
if (importance.length > 0) {
|
||||
plotParamImportancesBeta(importance, objectiveNames, theme.palette.mode)
|
||||
}
|
||||
}, [nObjectives, importance, theme.palette.mode])
|
||||
}, [objectiveNames, importance, theme.palette.mode])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material"
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import React, { FC, useEffect } from "react"
|
||||
import { Box, Typography, useTheme } from "@mui/material"
|
||||
import { plotlyDarkTemplate } from "../PlotlyDarkMode"
|
||||
|
||||
const plotDomId = "graph-intermediate-values"
|
||||
@@ -20,7 +20,7 @@ export const PlotIntermediateValues: FC<{
|
||||
!includePruned,
|
||||
logScale
|
||||
)
|
||||
}, [trials, theme.palette.mode, false, includePruned, logScale])
|
||||
}, [trials, theme.palette.mode, includePruned, logScale])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import UploadFileIcon from "@mui/icons-material/UploadFile"
|
||||
import {
|
||||
Card,
|
||||
CardActionArea,
|
||||
CardContent,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import React, {
|
||||
ChangeEvent,
|
||||
DragEventHandler,
|
||||
@@ -6,18 +14,10 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react"
|
||||
import { loadSQLite3Storage } from "../sqlite3"
|
||||
import { loadJournalStorage } from "../journalStorage"
|
||||
import { useSetRecoilState } from "recoil"
|
||||
import { loadJournalStorage } from "../journalStorage"
|
||||
import { loadSQLite3Storage } from "../sqlite3"
|
||||
import { studiesState } from "../state"
|
||||
import {
|
||||
Card,
|
||||
CardActionArea,
|
||||
CardContent,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import UploadFileIcon from "@mui/icons-material/UploadFile"
|
||||
|
||||
export const StorageLoader: FC = () => {
|
||||
const theme = useTheme()
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import React, { FC } from "react"
|
||||
import { Link, useParams } from "react-router-dom"
|
||||
import {
|
||||
AppBar,
|
||||
Typography,
|
||||
Container,
|
||||
Toolbar,
|
||||
Box,
|
||||
IconButton,
|
||||
useTheme,
|
||||
Card,
|
||||
CardContent,
|
||||
} from "@mui/material"
|
||||
import Grid2 from "@mui/material/Unstable_Grid2"
|
||||
import { Home } from "@mui/icons-material"
|
||||
import Brightness4Icon from "@mui/icons-material/Brightness4"
|
||||
import Brightness7Icon from "@mui/icons-material/Brightness7"
|
||||
import {
|
||||
AppBar,
|
||||
Box,
|
||||
Card,
|
||||
CardContent,
|
||||
Container,
|
||||
IconButton,
|
||||
Toolbar,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import Grid2 from "@mui/material/Unstable_Grid2"
|
||||
import React, { FC } from "react"
|
||||
import { Link, useParams } from "react-router-dom"
|
||||
import { useRecoilValue } from "recoil"
|
||||
import { studiesState } from "../state"
|
||||
import { TrialTable } from "./TrialTable"
|
||||
import { PlotHistory } from "./PlotHistory"
|
||||
import { PlotImportance } from "./PlotImportance"
|
||||
import { PlotIntermediateValues } from "./PlotIntermediateValues"
|
||||
import { TrialTable } from "./TrialTable"
|
||||
|
||||
const useStudyValue = (idx: number): Study | null => {
|
||||
const studies = useRecoilValue<Study[]>(studiesState)
|
||||
@@ -40,7 +40,7 @@ export const StudyDetail: FC<{
|
||||
<AppBar position="static">
|
||||
<Container
|
||||
sx={{
|
||||
["@media (min-width: 1280px)"]: {
|
||||
"@media (min-width: 1280px)": {
|
||||
maxWidth: "100%",
|
||||
},
|
||||
}}
|
||||
@@ -80,7 +80,7 @@ export const StudyDetail: FC<{
|
||||
</AppBar>
|
||||
<Container
|
||||
sx={{
|
||||
["@media (min-width: 1280px)"]: {
|
||||
"@media (min-width: 1280px)": {
|
||||
maxWidth: "100%",
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import React, { FC, useState, useMemo, useDeferredValue } from "react"
|
||||
import {
|
||||
AppBar,
|
||||
Typography,
|
||||
Container,
|
||||
Toolbar,
|
||||
Box,
|
||||
IconButton,
|
||||
MenuItem,
|
||||
useTheme,
|
||||
Card,
|
||||
CardContent,
|
||||
CardActionArea,
|
||||
TextField,
|
||||
InputAdornment,
|
||||
SvgIcon,
|
||||
} from "@mui/material"
|
||||
import { styled } from "@mui/system"
|
||||
import SortIcon from "@mui/icons-material/Sort"
|
||||
import { Search } from "@mui/icons-material"
|
||||
import Brightness4Icon from "@mui/icons-material/Brightness4"
|
||||
import Brightness7Icon from "@mui/icons-material/Brightness7"
|
||||
import SortIcon from "@mui/icons-material/Sort"
|
||||
import {
|
||||
AppBar,
|
||||
Box,
|
||||
Card,
|
||||
CardActionArea,
|
||||
CardContent,
|
||||
Container,
|
||||
IconButton,
|
||||
InputAdornment,
|
||||
MenuItem,
|
||||
SvgIcon,
|
||||
TextField,
|
||||
Toolbar,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material"
|
||||
import { styled } from "@mui/system"
|
||||
import React, { FC, useState, useMemo, useDeferredValue } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { useRecoilValue } from "recoil"
|
||||
import { studiesState } from "../state"
|
||||
import { Link } from "react-router-dom"
|
||||
import { Search } from "@mui/icons-material"
|
||||
import { StorageLoader } from "./StorageLoader"
|
||||
|
||||
export const StudyList: FC<{
|
||||
@@ -34,16 +34,16 @@ export const StudyList: FC<{
|
||||
const [_studyFilterText, setStudyFilterText] = useState<string>("")
|
||||
const [sortBy, setSortBy] = useState<"id-asc" | "id-desc">("id-asc")
|
||||
const studyFilterText = useDeferredValue(_studyFilterText)
|
||||
const studyFilter = (row: Study): boolean => {
|
||||
const keywords = studyFilterText.split(" ")
|
||||
return !keywords.every((k) => {
|
||||
if (k === "") {
|
||||
return true
|
||||
}
|
||||
return row.study_name.indexOf(k) >= 0
|
||||
})
|
||||
}
|
||||
const filteredStudies = useMemo(() => {
|
||||
const studyFilter = (row: Study): boolean => {
|
||||
const keywords = studyFilterText.split(" ")
|
||||
return !keywords.every((k) => {
|
||||
if (k === "") {
|
||||
return true
|
||||
}
|
||||
return row.study_name.indexOf(k) >= 0
|
||||
})
|
||||
}
|
||||
let filteredStudies: Study[] = studies.filter((s) => !studyFilter(s))
|
||||
if (sortBy === "id-desc") {
|
||||
filteredStudies = filteredStudies.reverse()
|
||||
@@ -96,7 +96,7 @@ export const StudyList: FC<{
|
||||
<AppBar position="static">
|
||||
<Container
|
||||
sx={{
|
||||
["@media (min-width: 1280px)"]: {
|
||||
"@media (min-width: 1280px)": {
|
||||
maxWidth: "100%",
|
||||
},
|
||||
}}
|
||||
@@ -126,7 +126,7 @@ export const StudyList: FC<{
|
||||
</AppBar>
|
||||
<Container
|
||||
sx={{
|
||||
["@media (min-width: 1280px)"]: {
|
||||
"@media (min-width: 1280px)": {
|
||||
maxWidth: "100%",
|
||||
},
|
||||
}}
|
||||
@@ -174,8 +174,9 @@ export const StudyList: FC<{
|
||||
color="text.secondary"
|
||||
component="div"
|
||||
>
|
||||
{"Direction: " +
|
||||
study.directions.map((d) => d.toUpperCase()).join(", ")}
|
||||
{`Direction: ${study.directions
|
||||
.map((d) => d.toUpperCase())
|
||||
.join(", ")}`}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { FC } from "react"
|
||||
|
||||
import { DataGridColumn, DataGrid } from "./DataGrid"
|
||||
import { DataGrid, DataGridColumn } from "./DataGrid"
|
||||
|
||||
export const TrialTable: FC<{
|
||||
study: Study
|
||||
@@ -34,7 +34,8 @@ export const TrialTable: FC<{
|
||||
}
|
||||
if (firstVal === undefined) {
|
||||
return ascending ? -1 : 1
|
||||
} else if (secondVal === undefined) {
|
||||
}
|
||||
if (secondVal === undefined) {
|
||||
return ascending ? 1 : -1
|
||||
}
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
@@ -61,7 +62,8 @@ export const TrialTable: FC<{
|
||||
}
|
||||
if (firstVal === undefined) {
|
||||
return ascending ? -1 : 1
|
||||
} else if (secondVal === undefined) {
|
||||
}
|
||||
if (secondVal === undefined) {
|
||||
return ascending ? 1 : -1
|
||||
}
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
@@ -77,6 +79,7 @@ export const TrialTable: FC<{
|
||||
columns.push(...objectiveColumns)
|
||||
}
|
||||
|
||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||
study.union_search_space.forEach((s) => {
|
||||
columns.push({
|
||||
field: "params",
|
||||
@@ -96,17 +99,19 @@ export const TrialTable: FC<{
|
||||
|
||||
if (firstVal === secondVal) {
|
||||
return 0
|
||||
} else if (firstVal && secondVal) {
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
} else if (firstVal) {
|
||||
return -1
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
if (firstVal && secondVal) {
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
}
|
||||
if (firstVal) {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||
study.union_user_attrs.forEach((attr_spec) => {
|
||||
columns.push({
|
||||
field: "user_attrs",
|
||||
@@ -126,13 +131,14 @@ export const TrialTable: FC<{
|
||||
|
||||
if (firstVal === secondVal) {
|
||||
return 0
|
||||
} else if (firstVal && secondVal) {
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
} else if (firstVal) {
|
||||
return -1
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
if (firstVal && secondVal) {
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
}
|
||||
if (firstVal) {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -33,9 +33,12 @@ interface JournalOpCreateTrial extends JournalOpBase {
|
||||
datetime_start?: string
|
||||
datetime_complete?: string
|
||||
distributions?: { [key: string]: string }
|
||||
params?: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
user_attrs?: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
system_attrs?: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
params?: { [key: string]: any }
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
user_attrs?: { [key: string]: any }
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
system_attrs?: { [key: string]: any }
|
||||
state?: number
|
||||
intermediate_values?: { [key: string]: number }
|
||||
value?: number
|
||||
@@ -65,6 +68,7 @@ interface JournalOpSetTrialIntermediateValue extends JournalOpBase {
|
||||
|
||||
interface JournalOpSetTrialUserAttr extends JournalOpBase {
|
||||
trial_id: number
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
user_attr: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
}
|
||||
|
||||
@@ -87,22 +91,25 @@ const trialStateNumToTrialState = (state: number): TrialState => {
|
||||
|
||||
const parseDistribution = (distribution: string): Distribution => {
|
||||
const distributionJson = JSON.parse(distribution)
|
||||
if (distributionJson["name"] === "IntDistribution") {
|
||||
if (distributionJson.name === "IntDistribution") {
|
||||
return {
|
||||
...distributionJson["attributes"],
|
||||
...distributionJson.attributes,
|
||||
type: "IntDistribution",
|
||||
}
|
||||
} else if (distributionJson["name"] === "FloatDistribution") {
|
||||
}
|
||||
if (distributionJson.name === "FloatDistribution") {
|
||||
return {
|
||||
...distributionJson["attributes"],
|
||||
...distributionJson.attributes,
|
||||
type: "FloatDistribution",
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (distributionJson.name === "CategoricalDistribution") {
|
||||
return {
|
||||
type: "CategoricalDistribution",
|
||||
choices: distributionJson["attributes"]["choices"],
|
||||
choices: distributionJson.attributes.choices,
|
||||
}
|
||||
}
|
||||
throw new Error(`Unexpected distribution: ${distribution}`)
|
||||
}
|
||||
|
||||
class JournalStorage {
|
||||
@@ -183,7 +190,9 @@ class JournalStorage {
|
||||
log.params === undefined || log.distributions === undefined
|
||||
? []
|
||||
: Object.entries(log.params).map(([name, value]) => {
|
||||
const distribution = parseDistribution(log.distributions![name])
|
||||
const distribution = parseDistribution(
|
||||
log.distributions?.[name] || ""
|
||||
)
|
||||
return {
|
||||
name: name,
|
||||
param_internal_value: value,
|
||||
@@ -191,11 +200,11 @@ class JournalStorage {
|
||||
param_external_value: (() => {
|
||||
if (distribution.type === "FloatDistribution") {
|
||||
return value.toString()
|
||||
} else if (distribution.type === "IntDistribution") {
|
||||
return value.toString()
|
||||
} else {
|
||||
return distribution.choices[value]
|
||||
}
|
||||
if (distribution.type === "IntDistribution") {
|
||||
return value.toString()
|
||||
}
|
||||
return distribution.choices[value]
|
||||
})(),
|
||||
distribution: distribution,
|
||||
}
|
||||
@@ -218,11 +227,11 @@ class JournalStorage {
|
||||
values: (() => {
|
||||
if (log.value !== undefined) {
|
||||
return [log.value]
|
||||
} else if (log.values !== undefined) {
|
||||
return log.values
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
if (log.values !== undefined) {
|
||||
return log.values
|
||||
}
|
||||
return undefined
|
||||
})(),
|
||||
params: params,
|
||||
intermediate_values: [],
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SetterOrUpdater } from "recoil"
|
||||
type SQLite3DB = {
|
||||
exec(options: {
|
||||
sql: string
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (...args: any[]) => void
|
||||
}): void
|
||||
}
|
||||
@@ -15,11 +15,11 @@ export const loadSQLite3Storage = (
|
||||
setter: SetterOrUpdater<Study[]>
|
||||
): void => {
|
||||
sqlite3InitModule({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
print: (...args: any): void => {
|
||||
console.log(args)
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
printErr: (...args: any): void => {
|
||||
console.log(args)
|
||||
},
|
||||
@@ -54,7 +54,7 @@ const getSchemaVersion = (db: SQLite3DB): string => {
|
||||
let schemaVersion = ""
|
||||
db.exec({
|
||||
sql: "SELECT version_num FROM alembic_version LIMIT 1",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
schemaVersion = vals[0]
|
||||
},
|
||||
@@ -75,11 +75,11 @@ const isGreaterSchemaVersion = (
|
||||
// return leftVersion > rightVersion
|
||||
const leftSuffix = leftVersion.split(".").reverse()[0]
|
||||
const rightSuffix = rightVersion.split(".").reverse()[0]
|
||||
leftVersion = leftVersion.replace(/\D/g, "")
|
||||
rightVersion = rightVersion.replace(/\D/g, "")
|
||||
const leftVersion_ = leftVersion.replace(/\D/g, "")
|
||||
const rightVersion_ = rightVersion.replace(/\D/g, "")
|
||||
|
||||
const left = Number(leftVersion)
|
||||
const right = Number(rightVersion)
|
||||
const left = Number(leftVersion_)
|
||||
const right = Number(rightVersion_)
|
||||
if (left === right) return leftSuffix > rightSuffix
|
||||
return left > right
|
||||
}
|
||||
@@ -91,7 +91,7 @@ const getStudies = (db: SQLite3DB, schemaVersion: string): Study[] => {
|
||||
"SELECT s.study_id, s.study_name, sd.direction, sd.objective" +
|
||||
" FROM studies AS s INNER JOIN study_directions AS sd" +
|
||||
" ON s.study_id = sd.study_id ORDER BY sd.study_direction_id",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
const studyId = vals[0]
|
||||
const studyName = vals[1]
|
||||
@@ -103,25 +103,27 @@ const getStudies = (db: SQLite3DB, schemaVersion: string): Study[] => {
|
||||
const union_search_space: SearchSpaceItem[] = []
|
||||
const union_user_attrs: AttributeSpec[] = []
|
||||
let intersection_search_space: Set<SearchSpaceItem> = new Set()
|
||||
trials.forEach((trial) => {
|
||||
|
||||
for (const trial of trials) {
|
||||
const userAttrs = getTrialUserAttributes(db, trial.trial_id)
|
||||
userAttrs.forEach((attr) => {
|
||||
for (const attr of userAttrs) {
|
||||
if (union_user_attrs.findIndex((s) => s.key === attr.key) === -1) {
|
||||
union_user_attrs.push({ key: attr.key, sortable: false })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const params = getTrialParams(db, trial.trial_id)
|
||||
const param_names = new Set<string>()
|
||||
params.forEach((param) => {
|
||||
for (const param of params) {
|
||||
param_names.add(param.name)
|
||||
if (
|
||||
union_search_space.findIndex((s) => s.name === param.name) === -1
|
||||
) {
|
||||
union_search_space.push({ name: param.name })
|
||||
}
|
||||
})
|
||||
}
|
||||
if (intersection_search_space.size === 0) {
|
||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||
param_names.forEach((s) => {
|
||||
intersection_search_space.add({
|
||||
name: s,
|
||||
@@ -136,7 +138,7 @@ const getStudies = (db: SQLite3DB, schemaVersion: string): Study[] => {
|
||||
}
|
||||
trial.params = params
|
||||
trial.user_attrs = userAttrs
|
||||
})
|
||||
}
|
||||
|
||||
if (objective === 0) {
|
||||
studies.push({
|
||||
@@ -164,10 +166,8 @@ const getTrials = (
|
||||
): Trial[] => {
|
||||
const trials: Trial[] = []
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT trial_id, number, state, datetime_start, datetime_complete FROM trials" +
|
||||
` WHERE study_id = ${studyId} ORDER BY number`,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT trial_id, number, state, datetime_start, datetime_complete FROM trials WHERE study_id = ${studyId} ORDER BY number`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
const trialId = vals[0]
|
||||
const state: TrialState =
|
||||
@@ -210,11 +210,8 @@ const getTrialValues = (
|
||||
const values: number[] = []
|
||||
if (isGreaterSchemaVersion(schemaVersion, "v3.0.0.c")) {
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT value, value_type" +
|
||||
` FROM trial_values WHERE trial_id = ${trialId}` +
|
||||
" ORDER BY objective",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT value, value_type FROM trial_values WHERE trial_id = ${trialId} ORDER BY objective`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
values.push(
|
||||
vals[1] === "INF_NEG"
|
||||
@@ -227,11 +224,8 @@ const getTrialValues = (
|
||||
})
|
||||
} else {
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT value" +
|
||||
` FROM trial_values WHERE trial_id = ${trialId}` +
|
||||
" ORDER BY objective",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT value FROM trial_values WHERE trial_id = ${trialId} ORDER BY objective`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
values.push(vals[0])
|
||||
},
|
||||
@@ -243,10 +237,8 @@ const getTrialValues = (
|
||||
const getTrialParams = (db: SQLite3DB, trialId: number): TrialParam[] => {
|
||||
const params: TrialParam[] = []
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT param_name, param_value, distribution_json" +
|
||||
` FROM trial_params WHERE trial_id = ${trialId}`,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT param_name, param_value, distribution_json FROM trial_params WHERE trial_id = ${trialId}`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
const distribution = parseDistributionJSON(vals[2])
|
||||
params.push({
|
||||
@@ -270,11 +262,11 @@ const paramInternalValueToExternalValue = (
|
||||
): CategoricalChoiceType => {
|
||||
if (distribution.type === "FloatDistribution") {
|
||||
return internalValue.toString()
|
||||
} else if (distribution.type === "IntDistribution") {
|
||||
return internalValue.toString()
|
||||
} else {
|
||||
return distribution.choices[internalValue]
|
||||
}
|
||||
if (distribution.type === "IntDistribution") {
|
||||
return internalValue.toString()
|
||||
}
|
||||
return distribution.choices[internalValue]
|
||||
}
|
||||
|
||||
const parseDistributionJSON = (t: string): Distribution => {
|
||||
@@ -287,7 +279,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: parsed.attributes.step as number,
|
||||
log: parsed.attributes.log as boolean,
|
||||
}
|
||||
} else if (parsed.name === "UniformDistribution") {
|
||||
}
|
||||
if (parsed.name === "UniformDistribution") {
|
||||
return {
|
||||
type: "FloatDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -295,7 +288,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: null,
|
||||
log: false,
|
||||
}
|
||||
} else if (parsed.name === "LogUniformDistribution") {
|
||||
}
|
||||
if (parsed.name === "LogUniformDistribution") {
|
||||
return {
|
||||
type: "FloatDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -303,7 +297,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: null,
|
||||
log: true,
|
||||
}
|
||||
} else if (parsed.name === "DiscreteUniformDistribution") {
|
||||
}
|
||||
if (parsed.name === "DiscreteUniformDistribution") {
|
||||
return {
|
||||
type: "FloatDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -311,7 +306,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: parsed.attributes.q,
|
||||
log: false,
|
||||
}
|
||||
} else if (parsed.name === "IntDistribution") {
|
||||
}
|
||||
if (parsed.name === "IntDistribution") {
|
||||
return {
|
||||
type: "IntDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -319,7 +315,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: parsed.attributes.step as number,
|
||||
log: parsed.attributes.log as boolean,
|
||||
}
|
||||
} else if (parsed.name === "IntUniformDistribution") {
|
||||
}
|
||||
if (parsed.name === "IntUniformDistribution") {
|
||||
return {
|
||||
type: "IntDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -327,7 +324,8 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: parsed.attributes.step as number,
|
||||
log: false,
|
||||
}
|
||||
} else if (parsed.name === "IntLogUniformDistribution") {
|
||||
}
|
||||
if (parsed.name === "IntLogUniformDistribution") {
|
||||
return {
|
||||
type: "IntDistribution",
|
||||
low: parsed.attributes.low as number,
|
||||
@@ -335,11 +333,10 @@ const parseDistributionJSON = (t: string): Distribution => {
|
||||
step: parsed.attributes.step as number,
|
||||
log: true,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
type: "CategoricalDistribution",
|
||||
choices: parsed.attributes.choices,
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: "CategoricalDistribution",
|
||||
choices: parsed.attributes.choices,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,10 +346,8 @@ const getTrialUserAttributes = (
|
||||
): Attribute[] => {
|
||||
const attrs: Attribute[] = []
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT key, value_json" +
|
||||
` FROM trial_user_attributes WHERE trial_id = ${trialId}`,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT key, value_json FROM trial_user_attributes WHERE trial_id = ${trialId}`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
attrs.push({
|
||||
key: vals[0],
|
||||
@@ -371,11 +366,8 @@ const getTrialIntermediateValues = (
|
||||
const values: TrialIntermediateValue[] = []
|
||||
if (isGreaterSchemaVersion(schemaVersion, "v3.0.0.c")) {
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT step, intermediate_value, intermediate_value_type" +
|
||||
` FROM trial_intermediate_values WHERE trial_id = ${trialId}` +
|
||||
" ORDER BY step",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT step, intermediate_value, intermediate_value_type FROM trial_intermediate_values WHERE trial_id = ${trialId} ORDER BY step`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
values.push({
|
||||
step: vals[0],
|
||||
@@ -392,11 +384,8 @@ const getTrialIntermediateValues = (
|
||||
})
|
||||
} else {
|
||||
db.exec({
|
||||
sql:
|
||||
"SELECT step, intermediate_value" +
|
||||
` FROM trial_intermediate_values WHERE trial_id = ${trialId}` +
|
||||
" ORDER BY step",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sql: `SELECT step, intermediate_value FROM trial_intermediate_values WHERE trial_id = ${trialId} ORDER BY step`,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
callback: (vals: any[]) => {
|
||||
values.push({
|
||||
step: vals[0],
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import React, { FC, useEffect } from "react"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import "./index.css"
|
||||
import { RecoilRoot, SetterOrUpdater, useSetRecoilState } from "recoil"
|
||||
import { App } from "./components/App"
|
||||
import { RecoilRoot, useSetRecoilState, SetterOrUpdater } from "recoil"
|
||||
import { studiesState } from "./state"
|
||||
import { loadSQLite3Storage } from "./sqlite3"
|
||||
import "./index.css"
|
||||
import { loadJournalStorage } from "./journalStorage"
|
||||
import { loadSQLite3Storage } from "./sqlite3"
|
||||
import { studiesState } from "./state"
|
||||
|
||||
export const AppWrapper: FC = () => {
|
||||
const setStudies = useSetRecoilState<Study[]>(studiesState)
|
||||
|
||||
// TODO(c-bata): Fix the type annotation
|
||||
const onceSetStudies: SetterOrUpdater<Study[]> = (
|
||||
setter: (currVal: Study[]) => Study[]
|
||||
): void => {
|
||||
@@ -17,6 +18,7 @@ export const AppWrapper: FC = () => {
|
||||
setStudies(studies)
|
||||
}
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
||||
useEffect(() => {
|
||||
window.addEventListener("message", (event) => {
|
||||
const message = event.data
|
||||
|
||||
Reference in New Issue
Block a user