Model store hooked up

This commit is contained in:
Gregory Schier
2026-03-08 15:42:18 -07:00
parent 0a616eb5e2
commit 96a22c68f2
10 changed files with 254 additions and 154 deletions

View File

@@ -50,7 +50,7 @@
"fuzzbunny": "^1.0.1",
"hexy": "^0.3.5",
"history": "^5.3.0",
"jotai": "^2.12.2",
"jotai": "^2.18.0",
"js-md5": "^0.8.3",
"lucide-react": "^0.525.0",
"mime": "^4.0.4",

View File

@@ -1,20 +1,30 @@
import "./main.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { type } from "@tauri-apps/plugin-os";
import { Button, HeaderSize } from "@yaakapp-internal/ui";
import classNames from "classnames";
import { StrictMode } from "react";
import { useState } from "react";
import { createStore, Provider, useAtomValue } from "jotai";
import { StrictMode, useState } from "react";
import { createRoot } from "react-dom/client";
import { rpc } from "./rpc";
import "./main.css";
import { listen, rpc } from "./rpc";
import { applyChange, dataAtom, httpExchangesAtom } from "./store";
const queryClient = new QueryClient();
const jotaiStore = createStore();
// Subscribe to model change events from the backend
listen("model_write", (payload) => {
jotaiStore.set(dataAtom, (prev) =>
applyChange(prev, "http_exchange", payload.model, payload.change),
);
});
function App() {
const [status, setStatus] = useState("Idle");
const [port, setPort] = useState<number | null>(null);
const [busy, setBusy] = useState(false);
const osType = type();
const exchanges = useAtomValue(httpExchangesAtom);
async function startProxy() {
setBusy(true);
@@ -45,7 +55,12 @@ function App() {
}
return (
<div className={classNames('h-full w-full grid grid-rows-[auto_1fr]', osType === 'linux' && 'border border-border-subtle')}>
<div
className={classNames(
"h-full w-full grid grid-rows-[auto_1fr]",
osType === "linux" && "border border-border-subtle",
)}
>
<HeaderSize
size="lg"
osType={osType}
@@ -56,41 +71,54 @@ function App() {
>
<div
data-tauri-drag-region
className="flex items-center h-full px-2 text-sm font-semibold text-text-subtle"
className="flex items-center px-2 text-sm font-semibold text-text-subtle"
>
Yaak Proxy
</div>
</HeaderSize>
<main className="overflow-auto p-6">
<section className="flex items-start">
<div className="flex w-full max-w-xl flex-col gap-4">
<div>
<p className="text-sm text-text-subtle">Status: {status}</p>
<p className="mt-1 text-sm text-text-subtle">
Port: {port ?? "Not running"}
</p>
</div>
<main className="overflow-auto p-4">
<div className="flex items-center gap-3 mb-4">
<Button disabled={busy} onClick={startProxy} size="sm" tone="primary">
Start Proxy
</Button>
<Button
disabled={busy}
onClick={stopProxy}
size="sm"
variant="border"
>
Stop Proxy
</Button>
<span className="text-xs text-text-subtlest">
{status}
{port != null && ` · :${port}`}
</span>
</div>
<div className="flex flex-wrap gap-3">
<Button
disabled={busy}
onClick={startProxy}
size="sm"
tone="primary"
>
Start Proxy
</Button>
<Button
disabled={busy}
onClick={stopProxy}
size="sm"
variant="border"
>
Stop Proxy
</Button>
</div>
</div>
</section>
<div className="text-xs font-mono">
{exchanges.length === 0 ? (
<p className="text-text-subtlest">No traffic yet</p>
) : (
<table className="w-full text-left">
<thead>
<tr className="text-text-subtlest border-b border-border-subtle">
<th className="py-1 pr-3 font-medium">Method</th>
<th className="py-1 pr-3 font-medium">URL</th>
<th className="py-1 pr-3 font-medium">Status</th>
</tr>
</thead>
<tbody>
{exchanges.map((ex) => (
<tr key={ex.id} className="border-b border-border-subtle">
<td className="py-1 pr-3">{ex.method}</td>
<td className="py-1 pr-3 truncate max-w-md">{ex.url}</td>
<td className="py-1 pr-3">{ex.resStatus ?? "—"}</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</main>
</div>
);
@@ -99,7 +127,9 @@ function App() {
createRoot(document.getElementById("root") as HTMLElement).render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<App />
<Provider store={jotaiStore}>
<App />
</Provider>
</QueryClientProvider>
</StrictMode>,
);

View File

@@ -13,8 +13,10 @@
"@tauri-apps/api": "^2.9.1",
"@tauri-apps/plugin-os": "^2.3.2",
"@yaakapp-internal/theme": "^1.0.0",
"@yaakapp-internal/model-store": "^1.0.0",
"@yaakapp-internal/ui": "^1.0.0",
"classnames": "^2.5.1",
"jotai": "^2.18.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"
},

11
apps/yaak-proxy/store.ts Normal file
View File

@@ -0,0 +1,11 @@
import { createModelStore } from "@yaakapp-internal/model-store";
import type { HttpExchange } from "../../crates-proxy/yaak-proxy-lib/bindings/gen_models";
export const { dataAtom, applyChange, listAtom, orderedListAtom } =
createModelStore<HttpExchange>();
export const httpExchangesAtom = orderedListAtom(
"http_exchange",
"createdAt",
"desc",
);