mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
OmniRoute v3.8.29 — 115 commits since v3.8.28. Full CHANGELOG + 41 i18n mirrors. All content quality gates green (build, unit 8/8, vitest 188/188, PR test policy, quality gates extended, docs sync, quality ratchet). Remaining red CI checks are pre-existing release flakes (coverage-shard/integration/node-compat teardown), a new transitive undici advisory in electron devDeps, and a workflow-level CodeQL fail (0 open alerts). VPS-validated by the operator.
98 lines
3.3 KiB
TypeScript
98 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useState } from "react";
|
|
import {
|
|
useLiveDashboard,
|
|
type UseLiveDashboardOptions,
|
|
type WsEventPayload,
|
|
} from "./useLiveDashboard";
|
|
import {
|
|
compressionEventToModel,
|
|
stepEventsToRunModel,
|
|
appendInFlightStep,
|
|
clearInFlightOnComplete,
|
|
type CompressionRunModel,
|
|
type InFlightCompressionRun,
|
|
} from "@/app/(dashboard)/dashboard/compression/studio/compressionFlowModel";
|
|
import type { CompressionCompletedPayload, CompressionStepPayload } from "@/lib/events/types";
|
|
|
|
// ── Constants ─────────────────────────────────────────────────────────────
|
|
|
|
const MAX_RUNS = 100;
|
|
|
|
// ── Accumulator (pure reducer — exported for unit tests) ─────────────────
|
|
|
|
/**
|
|
* Pure accumulator: prepend the new run and cap at `maxRuns`.
|
|
* Most-recent-first order.
|
|
*/
|
|
export function accumulateRun(
|
|
prev: CompressionRunModel[],
|
|
payload: CompressionCompletedPayload,
|
|
maxRuns = MAX_RUNS
|
|
): CompressionRunModel[] {
|
|
const model = compressionEventToModel(payload);
|
|
return [model, ...prev].slice(0, maxRuns);
|
|
}
|
|
|
|
// ── useLiveCompression hook ───────────────────────────────────────────────
|
|
|
|
export interface UseLiveCompressionReturn {
|
|
/** All accumulated runs, most-recent-first. */
|
|
runs: CompressionRunModel[];
|
|
/** The most recently received run, or null. */
|
|
lastRun: CompressionRunModel | null;
|
|
/** Quick lookup by requestId. */
|
|
getRunById: (requestId: string) => CompressionRunModel | undefined;
|
|
isConnected: boolean;
|
|
reconnect: () => void;
|
|
}
|
|
|
|
/**
|
|
* Subscribes to the `compression` WS channel and accumulates
|
|
* `CompressionRunModel[]` (most-recent-first, capped at 100).
|
|
*
|
|
* Mirrors the pattern of `useLiveComboStatus` and `useLiveRequests`.
|
|
*/
|
|
export function useLiveCompression(options?: UseLiveDashboardOptions): UseLiveCompressionReturn {
|
|
const [runs, setRuns] = useState<CompressionRunModel[]>([]);
|
|
const [inFlight, setInFlight] = useState<InFlightCompressionRun | null>(null);
|
|
|
|
const handleEvent = useCallback((event: WsEventPayload) => {
|
|
if (event.channel !== "compression") return;
|
|
if (event.event === "compression.step") {
|
|
setInFlight((prev) => appendInFlightStep(prev, event.data as CompressionStepPayload));
|
|
return;
|
|
}
|
|
if (event.event === "compression.completed") {
|
|
const payload = event.data as CompressionCompletedPayload;
|
|
setInFlight((prev) => clearInFlightOnComplete(prev, payload.requestId));
|
|
setRuns((prev) => accumulateRun(prev, payload));
|
|
}
|
|
}, []);
|
|
|
|
const { connection, reconnect } = useLiveDashboard({
|
|
channels: ["compression"],
|
|
onEvent: handleEvent,
|
|
...options,
|
|
});
|
|
|
|
const getRunById = useCallback(
|
|
(requestId: string) => runs.find((r) => r.requestId === requestId),
|
|
[runs]
|
|
);
|
|
|
|
const inFlightRun =
|
|
inFlight && inFlight.steps.length > 0 ? stepEventsToRunModel(inFlight.steps) : null;
|
|
|
|
return {
|
|
runs,
|
|
// Prefer the live in-flight run so the studio shows engines as they stream in (F3.3),
|
|
// falling back to the latest completed run.
|
|
lastRun: inFlightRun ?? runs[0] ?? null,
|
|
getRunById,
|
|
isConnected: connection.isConnected,
|
|
reconnect,
|
|
};
|
|
}
|