Finish the mobile performance pass

- Cache the model catalog once per user and each conversation's setting
  separately; clear both on logout and after model saves
- Compress hashed assets asynchronously with a byte budget and set Vary
- Memoize message parsing and throttle selection reads
- Debounce draft writes to localStorage
- Keep the composer editor on the page and focused, as before
- Add a bundle budget check and run it in CI
- Show a loading block while sessions load and a workspace avatar in the
  mobile conversation header
This commit is contained in:
2026-10-20 14:37:11 +01:00
parent c1a94fc9a5
commit 4f7e0a6bf0
38 changed files with 1320 additions and 334 deletions
@@ -0,0 +1,103 @@
import { describe, expect, test } from "bun:test";
import type { HarnessOverview } from "@/src/types";
import {
harnessCatalogFromOverview,
harnessSettingsFromOverview,
mergeHarnessOverview,
} from "./harness-overview-parts";
const overview: HarnessOverview = {
harness: "text",
title: "Text",
description: "Chats.",
required: true,
automatic: true,
model_id: 4,
provider_id: 1,
providers: [{ id: 1, name: "OpenRouter" }],
fallback: false,
enabled: true,
options: { voice: "alloy" },
models: [
{
id: 4,
provider_id: 1,
provider_name: "OpenRouter",
slug: "deepseek",
name: "DeepSeek",
free: true,
},
],
current: {
id: 4,
provider_id: 1,
provider_name: "OpenRouter",
slug: "deepseek",
name: "DeepSeek",
free: true,
source: "pinned",
},
candidate_count: 2,
inherit: false,
};
describe("harness overview parts", () => {
test("splits the install-wide catalog from the conversation's setting", () => {
const [catalog] = harnessCatalogFromOverview({ harnesses: [overview] });
const [setting] = harnessSettingsFromOverview({ harnesses: [overview] });
expect(catalog).toMatchObject({
harness: "text",
title: "Text",
providers: overview.providers,
models: overview.models,
});
expect(setting).not.toHaveProperty("models");
expect(setting).not.toHaveProperty("providers");
expect(setting).toMatchObject({
harness: "text",
model_id: 4,
provider_id: 1,
fallback: false,
enabled: true,
});
});
test("merges a cached catalog and setting back into the form's shape", () => {
const [catalog] = harnessCatalogFromOverview({ harnesses: [overview] });
const [setting] = harnessSettingsFromOverview({ harnesses: [overview] });
expect(
mergeHarnessOverview({ catalog: [catalog!], settings: [setting!] }),
).toEqual([overview]);
});
test("waits for both parts", () => {
const [catalog] = harnessCatalogFromOverview({ harnesses: [overview] });
expect(mergeHarnessOverview({ catalog: [catalog!], settings: [] })).toBeUndefined();
expect(mergeHarnessOverview({ catalog: [], settings: [] })).toBeUndefined();
});
test("keeps a picked model the catalog no longer lists", () => {
const [catalog] = harnessCatalogFromOverview({
harnesses: [{ ...overview, models: [] }],
});
const [setting] = harnessSettingsFromOverview({ harnesses: [overview] });
const [merged] = mergeHarnessOverview({ catalog: [catalog!], settings: [setting!] })!;
expect(setting?.pinned_model).toEqual(overview.models[0]);
expect(merged?.models).toEqual(overview.models);
});
test("keeps a provider the catalog no longer lists", () => {
const without_providers = { ...overview, providers: [], models: [] };
const [catalog] = harnessCatalogFromOverview({ harnesses: [without_providers] });
const [setting] = harnessSettingsFromOverview({ harnesses: [without_providers] });
const [merged] = mergeHarnessOverview({ catalog: [catalog!], settings: [setting!] })!;
expect(merged?.providers).toEqual([
{ id: 1, name: "Unavailable provider" },
]);
});
});