Test modülü eklendi

This commit is contained in:
2025-11-26 23:14:41 +03:00
parent c19351f434
commit f6b73dacd2
12 changed files with 490 additions and 29 deletions

View File

@@ -6,9 +6,17 @@ type LiveState = {
running: boolean;
};
type JobStream = {
logs: string[];
status?: string;
lastRunAt?: string;
lastMessage?: string;
};
type LiveContextValue = LiveState & {
startCounter: () => void;
stopCounter: () => void;
jobStreams: Record<string, JobStream>;
};
const LiveContext = createContext<LiveContextValue | undefined>(undefined);
@@ -16,6 +24,7 @@ const LiveContext = createContext<LiveContextValue | undefined>(undefined);
export const LiveProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const socket = useSocket();
const [state, setState] = useState<LiveState>({ value: 0, running: false });
const [jobStreams, setJobStreams] = useState<Record<string, JobStream>>({});
useEffect(() => {
if (!socket) return;
@@ -30,14 +39,45 @@ export const LiveProvider: React.FC<{ children: React.ReactNode }> = ({ children
socket.on("counter:update", handleUpdate);
socket.on("counter:stopped", handleStopped);
const handleJobLog = ({ jobId, line }: { jobId: string; line: string }) => {
if (!jobId) return;
setJobStreams((prev) => {
const current = prev[jobId] || { logs: [] };
const nextLogs = [...current.logs, line].slice(-200);
return { ...prev, [jobId]: { ...current, logs: nextLogs } };
});
};
const handleJobStatus = ({
jobId,
status,
lastRunAt,
lastMessage
}: {
jobId: string;
status?: string;
lastRunAt?: string;
lastMessage?: string;
}) => {
if (!jobId) return;
setJobStreams((prev) => {
const current = prev[jobId] || { logs: [] };
return { ...prev, [jobId]: { ...current, status, lastRunAt, lastMessage } };
});
};
socket.emit("counter:status", (payload: { value: number; running: boolean }) => {
setState({ value: payload.value, running: payload.running });
});
socket.on("job:log", handleJobLog);
socket.on("job:status", handleJobStatus);
return () => {
socket.off("counter:update", handleUpdate);
socket.off("counter:stopped", handleStopped);
socket.off("job:log", handleJobLog);
socket.off("job:status", handleJobStatus);
};
}, [socket]);
@@ -60,9 +100,10 @@ export const LiveProvider: React.FC<{ children: React.ReactNode }> = ({ children
value: state.value,
running: state.running,
startCounter,
stopCounter
stopCounter,
jobStreams
}),
[state, startCounter, stopCounter]
[state, startCounter, stopCounter, jobStreams]
);
return <LiveContext.Provider value={value}>{children}</LiveContext.Provider>;
@@ -73,3 +114,9 @@ export function useLiveCounter() {
if (!ctx) throw new Error("useLiveCounter LiveProvider içinde kullanılmalı");
return ctx;
}
export function useJobStream(jobId: string) {
const ctx = useContext(LiveContext);
if (!ctx) throw new Error("useJobStream LiveProvider içinde kullanılmalı");
return useMemo(() => ctx.jobStreams[jobId] || { logs: [], status: "idle" }, [ctx.jobStreams, jobId]);
}