Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v5 #8

Merged
merged 11 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:

- name: Build solver (standalone)
working-directory: apps/solver
run: bun build --minify --sourcemap --compile --bytecode --target=bun-${{ matrix.target }} --outfile=dist/solver-${{ matrix.outfile }} $(find dist -name '*.js')
run: bun build --minify --sourcemap --compile --bytecode --target=bun-${{ matrix.target }} --outfile=dist/solver-${{ matrix.outfile }} dist/index.js $(find dist -name '*.js' -not -name 'index.js')

- name: Build mock server
working-directory: apps/mock-server
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,6 @@ poetry.toml

# LSP config files
pyrightconfig.json

# Profiling data
*.prof
2 changes: 2 additions & 0 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@data-maki/schemas": "workspace:*",
"@radix-ui/colors": "^3.0.0",
"@remix-run/cloudflare": "2.12.0",
"@remix-run/cloudflare-pages": "2.12.0",
"@remix-run/react": "2.12.0",
Expand All @@ -29,6 +30,7 @@
"dataclass": "^2.1.1",
"eventsource-parser": "^2.0.1",
"hono": "^4.6.3",
"inter-ui": "^4.0.2",
"isbot": "^4.4.0",
"jotai": "^2.10.0",
"luxon": "^3.5.0",
Expand Down
10 changes: 1 addition & 9 deletions apps/frontend/src/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ const indexHtml = `
<html lang="en">
<head>
<title>Data Maki UI</title>
<link rel="preconnect" href="https://rsms.me/">
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/mauve.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/red.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/blue.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/green.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/yellow.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@radix-ui/colors@latest/orange.css">
</head>
<body>
<div id="app"><!-- Remix SPA --></body>
Expand All @@ -33,7 +25,7 @@ export default async function handleRequest(
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
loadContext: AppLoadContext,
_loadContext: AppLoadContext,
) {
const appHtml = renderToString(<RemixServer context={remixContext} url={request.url} />);

Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/app/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@supports (font-variation-settings: normal) {
:root {
font-family: "Inter var", sans-serif;
font-family: "InterVariable", sans-serif;
}
}

Expand Down
16 changes: 15 additions & 1 deletion apps/frontend/src/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ import type { PropsWithChildren } from "react";
import { Footer } from "./components/layout/Footer";
import { Header } from "./components/layout/Header";

import "./index.css";
import radixBlue from "@radix-ui/colors/blue.css?url";
import radixGreen from "@radix-ui/colors/green.css?url";
import radixMauve from "@radix-ui/colors/mauve.css?url";
import radixOrange from "@radix-ui/colors/orange.css?url";
import radixRed from "@radix-ui/colors/red.css?url";
import radixYellow from "@radix-ui/colors/yellow.css?url";
import interVariableStyle from "inter-ui/inter-variable.css?url";
import interStyle from "inter-ui/inter.css?url";
import globalStyle from "./index.css?url";

export function HydrateFallback() {
return (
Expand All @@ -20,6 +28,12 @@ export function HydrateFallback() {
export function Layout({ children }: PropsWithChildren) {
return (
<>
<link rel="stylesheet" href={interStyle} />
<link rel="stylesheet" href={interVariableStyle} />
{[radixMauve, radixRed, radixBlue, radixGreen, radixYellow, radixOrange].map((style) => (
<link key={style} rel="stylesheet" href={style} />
))}
<link rel="stylesheet" href={globalStyle} />
<UIProvider>{children}</UIProvider>
<Scripts />
</>
Expand Down
76 changes: 47 additions & 29 deletions apps/frontend/src/app/routes/replay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,22 @@ export default function Page() {

const boards: string[][] = [structuredClone(replayInfo.problem.board.start)];

for (const op of replayInfo.answer.ops) {
const afterBoard = easyKatanuki(replayInfo.problem, op);
for (const [i, op] of replayInfo.answer.ops.entries()) {
try {
const afterBoard = easyKatanuki(replayInfo.problem, op);

replayInfo.problem.board.start = afterBoard;
replayInfo.problem.board.start = afterBoard;

boards.push(afterBoard);
boards.push(afterBoard);
} catch (e) {
if (e instanceof Error) {
throw new Error(`Failed to apply operation ${i + 1}`, { cause: e });
}

console.error(e);

throw new Error(`Failed to apply operation ${i + 1}`);
}
}

replayInfo.problem.board.start = boards[0];
Expand Down Expand Up @@ -98,31 +108,39 @@ export default function Page() {
</Heading>
{(board && extraOpInfo) || turn === turns - 1 ? (
<>
<Box as="section" my={4}>
<Heading as="h3" size="md" fontWeight="regular" lineHeight={1}>
Delta
</Heading>
{delta ? (
<Flex gap="md">
<HStack gap="md">
<BoardCell cell={"0"} size="32px" />
<Text>{delta[0]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"1"} size="32px" />
<Text>{delta[1]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"2"} size="32px" />
<Text>{delta[2]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"3"} size="32px" />
<Text>{delta[3]}</Text>
</HStack>
</Flex>
) : null}
</Box>
<HStack>
<Box as="section" my={4}>
<Heading as="h3" size="md" fontWeight="regular" lineHeight={1}>
Delta
</Heading>
{delta && (
<Flex gap="md">
<HStack gap="md">
<BoardCell cell={"0"} size="32px" />
<Text>{delta[0]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"1"} size="32px" />
<Text>{delta[1]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"2"} size="32px" />
<Text>{delta[2]}</Text>
</HStack>
<HStack gap="md">
<BoardCell cell={"3"} size="32px" />
<Text>{delta[3]}</Text>
</HStack>
</Flex>
)}
</Box>
<Box as="section" my={4}>
<Heading as="h3" size="md" fontWeight="regular" lineHeight={1}>
Pattern
</Heading>
<p>{replayInfo.answer.ops[turn] ? replayInfo.answer.ops[turn].p : "None"}</p>
</Box>
</HStack>
<Grid templateColumns="1fr 1fr" w="100%" placeItems="start" gap={4}>
<Heading as="h3" size="md" fontWeight="regular" lineHeight={1}>
Start
Expand Down
6 changes: 3 additions & 3 deletions apps/solver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
"axios": "^1.7.7",
"comlink": "^4.4.1",
"fast-deep-equal": "^3.1.3",
"hono": "^4.6.3",
"hono": "^4.6.5",
"hono-pino": "^0.3.0",
"loglayer": "^4.8.0",
"pino": "^9.4.0",
"pino-pretty": "^11.2.2",
"pino": "^9.5.0",
"pino-pretty": "^11.3.0",
"pino-roll": "^2.1.0",
"reactive-channel": "^3.1.2",
"universal-stores": "^2.4.3",
Expand Down
10 changes: 8 additions & 2 deletions apps/solver/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ const copyFiles = async (from: string[], to: string) => {

console.time("Finished building solver");

await Bun.build({
const results = await Bun.build({
entrypoints: ["./src/index.ts"],
splitting: true,
sourcemap: "linked",
plugins: [
typia({
Expand All @@ -46,6 +45,13 @@ await Bun.build({
},
});

if (!results.success) {
console.error("Failed to build solver");
console.error(results.logs);

process.exit(1);
}

console.log("Copying files...");

const files = await Array.fromAsync(new Glob("../../packages/algorithm/dist/workers/*.worker.js").scan());
Expand Down
4 changes: 4 additions & 0 deletions apps/solver/scripts/hotfix-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bun run build
bun build --minify --compile --target=bun-linux-x64 --outfile=dist/solver-hotfix-linux-x64 dist/index.js $(find dist -name '*.js' -not -name 'index.js')

dist/solver-hotfix-linux-x64
81 changes: 57 additions & 24 deletions apps/solver/src/features/algorithm/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ALGO_VERSION } from "@/constants/env";
import { LATEST_VERSION, type SolveFunc, getSolveFunc, isSolveFuncVersion } from "@data-maki/algorithm";
import type { UIMessageEventBase } from "@data-maki/schemas";
import type { Answer, Problem, UIMessageEventBase } from "@data-maki/schemas";
import type { SolveStartEvent } from "@data-maki/schemas";
import type { SolveProgressEvent } from "@data-maki/schemas";
import type { SolveFinishedEvent } from "@data-maki/schemas";
Expand All @@ -9,6 +9,7 @@ import type { LogLayer } from "loglayer";
import type { ChannelTx, ReadonlyStore } from "reactive-channel";
import { span } from "../../logging";
import { DoneState } from "../../state/done.ts";
import { IdleState } from "../../state/idle.ts";
import { StateManager } from "../../state/manager.ts";
import { SolvingState } from "../../state/solving.ts";
import { FeatureBase } from "../base";
Expand Down Expand Up @@ -53,6 +54,36 @@ export class AlgorithmFeature extends FeatureBase {
}
}

private async submitAnswer(id: string, problem: Problem, answer: Answer, finalBoard?: string[]) {
let correct = true;

if (finalBoard) {
correct = deepEqual(finalBoard, problem.board.goal);

if (correct) {
this.log
.withMetadata({
id,
turns: answer.ops.length,
})
.info("Answer is correct");
} else {
this.log
.withMetadata({
id,
turns: answer.ops.length,
expected: problem.board.goal,
actual: finalBoard,
})
.error("Answer is incorrect");
}
}

const revision = await this.serverComm.submitAnswer(id, answer);

return [correct, revision] as const;
}

init() {}

async start() {
Expand Down Expand Up @@ -80,40 +111,36 @@ export class AlgorithmFeature extends FeatureBase {
board: solvingState.problem.board,
general: solvingState.problem.general,
} satisfies SolveStartEvent);

solvingState.workers = workers;
},
(workerId, turns) => {
async (workerId, answer) => {
this.sendEvent({
eventName: "solve.progress",
solveId: solvingState.id,
workerId,
turns,
turns: answer.n,
} satisfies SolveProgressEvent);
},
);

const correct = deepEqual(finalBoard, solvingState.problem.board.goal);
if (solvingState.currentShortestAnswer === null || answer.n < solvingState.currentShortestAnswer.n) {
solvingState.currentShortestAnswer = answer;

if (correct) {
this.log
.withMetadata({
id: solvingState.id,
turns: answer.ops.length,
})
.info("Answer is correct");
} else {
this.log
.withMetadata({
id: solvingState.id,
turns: answer.ops.length,
expected: solvingState.problem.board.goal,
actual: finalBoard,
})
.error("Answer is incorrect");
}
const [, revision] = await this.submitAnswer(solvingState.id, solvingState.problem, answer);

this.log
.withMetadata({
id: solvingState.id,
turns: answer.ops.length,
revision,
})
.info("Answer updated");
}
},
);

scope.end();

const revision = await this.serverComm.submitAnswer(solvingState.id, solvingState.problem, answer);
const [correct, revision] = await this.submitAnswer(solvingState.id, solvingState.problem, answer, finalBoard);

this.sendEvent({
eventName: "solve.finished",
Expand All @@ -124,6 +151,12 @@ export class AlgorithmFeature extends FeatureBase {
} satisfies SolveFinishedEvent);

StateManager.instance.setState(new DoneState(solvingState.id, answer));

setTimeout(() => {
StateManager.instance.setState(IdleState.instance);

IdleState.instance.oldProblem = solvingState.problem;
}, 1000);
});
}
}
8 changes: 1 addition & 7 deletions apps/solver/src/features/server-comm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class ServerCommunicatorFeature extends FeatureBase {
}
}

async submitAnswer(id: string, problem: Problem, answer: Answer): Promise<number> {
async submitAnswer(id: string, answer: Answer): Promise<number> {
const scope = span(
this.log.withMetadata({
answerId: id,
Expand All @@ -108,12 +108,6 @@ export class ServerCommunicatorFeature extends FeatureBase {

scope.end();

setTimeout(() => {
StateManager.instance.setState(IdleState.instance);

IdleState.instance.oldProblem = problem;
}, 1000);

return revision;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/solver/src/features/ui-comm/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const createRouteDefinition = <T extends Env>(app: Hono<T>) =>
eventToSSE({
eventName: "solve.start",
solveId: solvingState.id,
workers: 1, // TODO: Implement multi-worker solving
workers: solvingState.workers,
startedAt: solvingState.startedAt,
board: solvingState.problem.board,
general: solvingState.problem.general,
Expand Down
Loading
Loading