1import { NodeId, PlanId, ProjectId, RunId } from "@t3tools/contracts";
2import {
3 getLatestThreadForProject,
4 sortActiveThreadsByOrderKey,
5 sortPinnedThreadsByOrderKey,
6 sortThreads,
7} from "@t3tools/client-runtime/state/thread-sort";
8import { formatHourShort, formatRelativeHourShort } from "@t3tools/shared/usageFormat";
9import { describe, test } from "vite-plus/test";
10
11import { makeThreadProjectionFixture } from "./test-fixtures";
12import { deriveActivePlanState } from "./session-logic";
13
14const projectId = ProjectId.make("benchmark-project");
15const runId = RunId.make("benchmark-run");
16const start = Date.parse("2026-08-11T00:00:00.000Z");
17const threads = Array.from({ length: 1_000 }, (_, index) => {
18 const timestamp = new Date(start + ((index * 997) % 1_000) * 60_000).toISOString();
19 return {
20 id: `thread-${index}`,
21 projectId,
22 archivedAt: null,
23 createdAt: timestamp,
24 updatedAt: timestamp,
25 latestUserMessageAt: timestamp,
26 unsettledAt: null,
27 };
28});
29const baseProjection = makeThreadProjectionFixture();
30const projection = {
31 ...baseProjection,
32 plans: Array.from({ length: 5 }, (_, index) => ({
33 id: PlanId.make(`plan-${index}`),
34 runId,
35 threadId: baseProjection.thread.id,
36 nodeId: NodeId.make("bench-node"),
37 status: "active" as const,
38 kind: "todo_list" as const,
39 steps: [{ id: "check", text: "Run checks", status: "running" as const }],
40 })),
41};
42const hours = Array.from({ length: 24 }, (_, index) =>
43 new Date(start + index * 3_600_000).toISOString(),
44);
45const referenceTime = "2026-08-12T00:00:00.000Z";
46
47describe("client performance", () => {
48 test("sort 1000 threads by recent activity", async ({ bench }) => {
49 await bench("sort", () => {
50 sortThreads(threads, "updated_at");
51 }).run();
52 });
53 test("sort 1000 active threads", async ({ bench }) => {
54 await bench("sort", () => {
55 sortActiveThreadsByOrderKey(threads);
56 }).run();
57 });
58 test("sort 1000 keyless pinned threads", async ({ bench }) => {
59 await bench("sort", () => {
60 sortPinnedThreadsByOrderKey(threads);
61 }).run();
62 });
63 test("select latest project thread from 1000 threads", async ({ bench }) => {
64 await bench("select", () => {
65 getLatestThreadForProject(threads, projectId, "updated_at");
66 }).run();
67 });
68 test("derive current plan from 5 normalized plans", async ({ bench }) => {
69 await bench("derive", () => {
70 deriveActivePlanState(projection, runId);
71 }).run();
72 });
73 test("format 24 hourly usage labels and tooltips", async ({ bench }) => {
74 await bench("format", () => {
75 hours.map((hour) => [
76 formatHourShort(hour, "America/New_York"),
77 formatRelativeHourShort(hour, referenceTime, "America/New_York"),
78 ]);
79 }).run();
80 });
81});