diff --git a/web/boneyard.config.json b/web/boneyard.config.json index 8f63610ee..36bcb0d3b 100644 --- a/web/boneyard.config.json +++ b/web/boneyard.config.json @@ -139,8 +139,8 @@ "timeline-notificationspreview--skeleton-fixture": { "route": "/iframe.html?id=timeline-notificationspreview--skeleton-fixture&viewMode=story" }, - "repo-pulls-pulldiff--skeleton-fixture": { - "route": "/iframe.html?id=repo-pulls-pulldiff--skeleton-fixture&viewMode=story" + "repo-diffview--skeleton-fixture": { + "route": "/iframe.html?id=repo-diffview--skeleton-fixture&viewMode=story" }, "repo-difffilecard--skeleton-fixture": { "route": "/iframe.html?id=repo-difffilecard--skeleton-fixture&viewMode=story" diff --git a/web/src/lib/api/pullDiff.test.ts b/web/src/lib/api/repoDiff.test.ts similarity index 99% rename from web/src/lib/api/pullDiff.test.ts rename to web/src/lib/api/repoDiff.test.ts index c6c6c0c39..82ad4c43c 100644 --- a/web/src/lib/api/pullDiff.test.ts +++ b/web/src/lib/api/repoDiff.test.ts @@ -7,9 +7,8 @@ import { isDiffTooLarge, fetchSides, loadDiff, - resolveChange, - type PullDiffFile -} from "$lib/api/pullDiff"; + resolveChange +} from "$lib/api/repoDiff"; import type { MirrorFileDiff } from "$lib/api/gitmirror"; const src = (path: string, extra: Partial = {}) => ({ diff --git a/web/src/lib/api/pullDiff.ts b/web/src/lib/api/repoDiff.ts similarity index 94% rename from web/src/lib/api/pullDiff.ts rename to web/src/lib/api/repoDiff.ts index 23511f340..d6fada352 100644 --- a/web/src/lib/api/pullDiff.ts +++ b/web/src/lib/api/repoDiff.ts @@ -43,15 +43,15 @@ export interface InterdiffSpec { changeId?: string; } -export type PullDiffSpec = DiffSpec | InterdiffSpec; +export type RepoDiffSpec = DiffSpec | InterdiffSpec; -export interface PullDiffDeps { +export interface RepoDiffDeps { ctx: BobbinContext; // where the blob text comes from; the diff payload carries line numbers only git: GitTarget; } -export interface PullDiffFile { +export interface RepoDiffFile { // stable across sides, used for anchors key: string; name: string; @@ -71,8 +71,8 @@ export interface PullDiffFile { export type ContentsSource = { inlineOld?: false; oldRef: string; newRef: string } | { inlineOld: true; newRef: string }; -export interface PullDiff { - files: PullDiffFile[]; +export interface RepoDiff { + files: RepoDiffFile[]; stat: DiffStat; contents: ContentsSource; } @@ -129,13 +129,13 @@ export const cappedFetch = return new Response(stream, { status: response.status, headers: response.headers }); }; -export const loadDiff = (deps: PullDiffDeps, spec: PullDiffSpec): Promise => { +export const loadDiff = (deps: RepoDiffDeps, spec: RepoDiffSpec): Promise => { if (spec.kind === "diff") return plainDiff(deps, spec.repo, spec.version); if (!spec.changeId) return interdiff(deps, spec.repo, spec.oldVersion, spec.version); return oneChange(deps, spec); }; -const plainDiff = async (deps: PullDiffDeps, repo: Did, version: Revspec): Promise => { +const plainDiff = async (deps: RepoDiffDeps, repo: Did, version: Revspec): Promise => { const { diffs } = await getDiff(deps.ctx, { baseRepo: repo, baseCommit: version.base, @@ -151,11 +151,11 @@ const plainDiff = async (deps: PullDiffDeps, repo: Did, version: Revspec): Promi // an interdiff's right side is the new version's head tree, so it reads like any // other diff -- its left side comes inlined, see `ContentsSource` const interdiff = async ( - deps: PullDiffDeps, + deps: RepoDiffDeps, repo: Did, oldVersion: Revspec, version: Revspec -): Promise => { +): Promise => { const { diffs } = await getInterdiff(deps.ctx, { baseRepo: repo, baseCommit1: oldVersion.base, @@ -169,7 +169,7 @@ const interdiff = async ( // a change id names the same logical commit in both versions, so narrowing to it // means interdiffing that one commit's span on each side -const oneChange = async (deps: PullDiffDeps, spec: InterdiffSpec): Promise => { +const oneChange = async (deps: RepoDiffDeps, spec: InterdiffSpec): Promise => { const [oldCommits, newCommits] = await Promise.all([ listLog(deps.ctx, spec.repo, spec.oldVersion), listLog(deps.ctx, spec.repo, spec.version) @@ -225,16 +225,16 @@ export const resolveChange = ( // the diff endpoint answers metadata only -- `diffSrc` is path/oid/size/flags and // a hunk is aligned line numbers -- so the text comes from the blob endpoint and // pierre diffs the two sides itself -const buildDiff = (diffs: MirrorFileDiff[], contents: ContentsSource): PullDiff => { +const buildDiff = (diffs: MirrorFileDiff[], contents: ContentsSource): RepoDiff => { const stat: DiffStat = { insertions: 0, deletions: 0, files_changed: diffs.length }; - const files = diffs.map((file): PullDiffFile => { + const files = diffs.map((file): RepoDiffFile => { const fileStat = diffFileStat(file); stat.insertions += fileStat.insertions; stat.deletions += fileStat.deletions; const kind = diffFileKind(file); const name = file.rhsSrc.path || file.lhsSrc.path; - const base: PullDiffFile = { + const base: RepoDiffFile = { key: `${file.lhsSrc.path}→${file.rhsSrc.path}`, name, oldName: kind === "renamed" ? file.lhsSrc.path : undefined, @@ -297,9 +297,9 @@ const sideContents = async ( }; export const fetchSides = async ( - deps: PullDiffDeps, + deps: RepoDiffDeps, contents: ContentsSource, - file: PullDiffFile + file: RepoDiffFile ): Promise => { const sides = file.sides; if (!sides) return { note: file.note ?? "Contents could not be loaded." }; diff --git a/web/src/lib/bones/repo-pulls-pulldiff--skeleton-fixture.bones.json b/web/src/lib/bones/repo-diffview--skeleton-fixture.bones.json similarity index 99% rename from web/src/lib/bones/repo-pulls-pulldiff--skeleton-fixture.bones.json rename to web/src/lib/bones/repo-diffview--skeleton-fixture.bones.json index f8761f63f..c72eff9eb 100644 --- a/web/src/lib/bones/repo-pulls-pulldiff--skeleton-fixture.bones.json +++ b/web/src/lib/bones/repo-diffview--skeleton-fixture.bones.json @@ -1,7 +1,7 @@ { "breakpoints": { "375": { - "name": "repo-pulls-pulldiff--skeleton-fixture", + "name": "repo-diffview--skeleton-fixture", "viewportWidth": 343, "width": 343, "height": 824, @@ -31,7 +31,7 @@ ] }, "768": { - "name": "repo-pulls-pulldiff--skeleton-fixture", + "name": "repo-diffview--skeleton-fixture", "viewportWidth": 736, "width": 736, "height": 2118, @@ -256,7 +256,7 @@ ] }, "1024": { - "name": "repo-pulls-pulldiff--skeleton-fixture", + "name": "repo-diffview--skeleton-fixture", "viewportWidth": 992, "width": 992, "height": 2118, @@ -480,7 +480,7 @@ ] }, "1440": { - "name": "repo-pulls-pulldiff--skeleton-fixture", + "name": "repo-diffview--skeleton-fixture", "viewportWidth": 1408, "width": 1408, "height": 2118, diff --git a/web/src/lib/components/repo/CommitView.stories.svelte b/web/src/lib/components/repo/CommitView.stories.svelte index d79e861f0..44441dec8 100644 --- a/web/src/lib/components/repo/CommitView.stories.svelte +++ b/web/src/lib/components/repo/CommitView.stories.svelte @@ -2,7 +2,7 @@ import { defineMeta, type StoryContext } from "@storybook/addon-svelte-csf"; import { expect, waitFor } from "storybook/test"; import type { NiceCommit } from "$lib/api/diff"; - import type { PullDiff, PullDiffDeps } from "$lib/api/pullDiff"; + import type { RepoDiff, RepoDiffDeps } from "$lib/api/repoDiff"; import { toCommitDetail } from "$lib/api/repo"; import CommitView from "$lib/components/repo/CommitView.svelte"; @@ -18,7 +18,7 @@ // both sides inline their text, so `fetchSides` never reaches for a blob and // `deps` is never touched - const deps = { ctx: {}, git: {} } as unknown as PullDiffDeps; + const deps = { ctx: {}, git: {} } as unknown as RepoDiffDeps; const before = `export interface Palette { background: string; @@ -84,7 +84,7 @@ export const palette: Palette = { note: "This is a binary file and will not be displayed." } ] - } satisfies PullDiff + } satisfies RepoDiff }; type PlayContext = Pick>, "canvas" | "canvasElement">; diff --git a/web/src/lib/components/repo/CommitView.svelte b/web/src/lib/components/repo/CommitView.svelte index 3ee466299..209190773 100644 --- a/web/src/lib/components/repo/CommitView.svelte +++ b/web/src/lib/components/repo/CommitView.svelte @@ -4,17 +4,17 @@ import { untrack } from "svelte"; import { loadDiff, - type PullDiff as MirrorDiff, - type PullDiffDeps, - type PullDiffSpec - } from "$lib/api/pullDiff"; + type RepoDiff, + type RepoDiffDeps, + type RepoDiffSpec + } from "$lib/api/repoDiff"; import { browser } from "$app/environment"; import { formatPatchUrl } from "$lib/api/knotmirror"; import { getPatchStream } from "$lib/api/patchStream"; import type { CommitDetail } from "$lib/api/repo"; import { FULL_HASH_RE } from "$lib/api/repo"; import CommitHeader from "$lib/components/repo/CommitHeader.svelte"; - import PullDiff from "$lib/components/repo/pulls/PullDiff.svelte"; + import DiffView from "$lib/components/repo/DiffView.svelte"; import type { DiffStyle } from "$lib/components/repo/pierre"; import TabPanel from "$lib/components/ui/TabPanel.svelte"; import type { CommitStatuses } from "$lib/api/commitStatuses"; @@ -33,10 +33,10 @@ // the commit diff always comes from the mirror. pendingSpec: the payload was // too big to buffer through ssr, so the browser fetches it on mount mirror: { - diff?: MirrorDiff; + diff?: RepoDiff; error?: string; - pendingSpec?: PullDiffSpec; - deps: PullDiffDeps; + pendingSpec?: RepoDiffSpec; + deps: RepoDiffDeps; }; // side-by-side or stacked diffStyle?: DiffStyle; @@ -58,7 +58,7 @@ const base = $derived(`/${ownerHandle}/${repoName}`); - let deferred = $state<{ spec?: PullDiffSpec; diff?: MirrorDiff; error?: string }>({}); + let deferred = $state<{ spec?: RepoDiffSpec; diff?: RepoDiff; error?: string }>({}); $effect(() => { const spec = mirror.pendingSpec; if (!spec || deferred.spec === spec) return; @@ -110,7 +110,7 @@ - boolean; onSetOpen?: (key: string, open: boolean) => void; diff --git a/web/src/lib/components/repo/pulls/PullDiff.stories.svelte b/web/src/lib/components/repo/DiffView.stories.svelte similarity index 88% rename from web/src/lib/components/repo/pulls/PullDiff.stories.svelte rename to web/src/lib/components/repo/DiffView.stories.svelte index 39f1e0c4e..e985af8e0 100644 --- a/web/src/lib/components/repo/pulls/PullDiff.stories.svelte +++ b/web/src/lib/components/repo/DiffView.stories.svelte @@ -1,23 +1,23 @@ {#if loading && !diff} - + {:else}
{#key diff} - ({ fetchSides: vi.fn(), @@ -8,7 +8,7 @@ const { fetchSides, parseDiffInWorker, streamPatchInWorker } = vi.hoisted(() => streamPatchInWorker: vi.fn() })); -vi.mock("$lib/api/pullDiff", () => ({ fetchSides })); +vi.mock("$lib/api/repoDiff", () => ({ fetchSides })); vi.mock("$lib/components/repo/diffRpc", () => ({ parseDiffInWorker, streamPatchInWorker })); // the real one fetches and parses in a worker, answering in batches; the mock @@ -36,24 +36,24 @@ const side = (name: string, oid: string) => ({ size: 12 }); -const file = (name: string): PullDiffFile => ({ +const file = (name: string): RepoDiffFile => ({ ...base(name), sides: { lhs: side(name, "a"), rhs: side(name, "b") } }); -const noteFile = (name: string): PullDiffFile => ({ ...base(name), note: "binary" }); +const noteFile = (name: string): RepoDiffFile => ({ ...base(name), note: "binary" }); -const diffOf = (...files: PullDiffFile[]): PullDiff => ({ +const diffOf = (...files: RepoDiffFile[]): RepoDiff => ({ files, stat: { insertions: 1, deletions: 0, files_changed: files.length }, contents: { oldRef: "old", newRef: "new" } }); -const harness = (diff: PullDiff) => { +const harness = (diff: RepoDiff) => { let entries: Record = {}; let patchExpected = false; const queue = createDiffQueue({ - deps: () => ({}) as PullDiffDeps, + deps: () => ({}) as RepoDiffDeps, diff: () => diff, entry: (key) => entries[key], put: (parsed) => (entries = { ...entries, ...parsed }), @@ -229,7 +229,7 @@ describe("createDiffQueue", () => { it("matches a renamed file through the patch's previous name", async () => { patchYielding([{ name: "new.ts", prevName: "old.ts", hunks: [] }]); - const renamed: PullDiffFile = { ...file("new.ts"), oldName: "old.ts" }; + const renamed: RepoDiffFile = { ...file("new.ts"), oldName: "old.ts" }; const h = harness(diffOf(renamed)); await h.queue.applyPatch("/commit.diff", new AbortController().signal); @@ -241,7 +241,7 @@ describe("createDiffQueue", () => { const order: string[] = []; const gate = deferred(); fetchSides.mockImplementation( - async (_deps: unknown, _contents: unknown, f: PullDiffFile) => { + async (_deps: unknown, _contents: unknown, f: RepoDiffFile) => { order.push(f.name); await gate.promise; return { diff --git a/web/src/lib/components/repo/pulls/diffQueue.ts b/web/src/lib/components/repo/diffQueue.ts similarity index 94% rename from web/src/lib/components/repo/pulls/diffQueue.ts rename to web/src/lib/components/repo/diffQueue.ts index 517b579a2..3218fdca5 100644 --- a/web/src/lib/components/repo/pulls/diffQueue.ts +++ b/web/src/lib/components/repo/diffQueue.ts @@ -1,13 +1,13 @@ import type { FileDiffMetadata } from "@pierre/diffs"; -import { fetchSides, type PullDiff, type PullDiffDeps, type PullDiffFile } from "$lib/api/pullDiff"; +import { fetchSides, type RepoDiff, type RepoDiffDeps, type RepoDiffFile } from "$lib/api/repoDiff"; import { parseDiffInWorker, streamPatchInWorker } from "$lib/components/repo/diffRpc"; import type { DiffEntry } from "$lib/components/repo/fileDiff"; export type { DiffEntry }; export interface DiffQueueHost { - deps: () => PullDiffDeps; - diff: () => PullDiff; + deps: () => RepoDiffDeps; + diff: () => RepoDiff; entry: (key: string) => DiffEntry | undefined; put: (parsed: Record) => void; /** true while a patch is still expected to deliver the whole diff */ @@ -36,8 +36,8 @@ export const createDiffQueue = (host: DiffQueueHost): DiffQueue => { let focusIndex = 0; let indexed: { - files: PullDiffFile[]; - byKey: Map; + files: RepoDiffFile[]; + byKey: Map; }; const byKey = () => { const files = host.diff().files; @@ -83,7 +83,7 @@ export const createDiffQueue = (host: DiffQueueHost): DiffQueue => { const backoff = (attempt: number) => new Promise((resolve) => setTimeout(resolve, 300 * 3 ** attempt + Math.random() * 200)); - const fetchWithRetry = async (file: PullDiffFile) => { + const fetchWithRetry = async (file: RepoDiffFile) => { for (let attempt = 0; ; attempt++) { try { return await fetchSides(host.deps(), host.diff().contents, file); @@ -94,7 +94,7 @@ export const createDiffQueue = (host: DiffQueueHost): DiffQueue => { } }; - const fill = async (file: PullDiffFile) => { + const fill = async (file: RepoDiffFile) => { running++; inFlight.add(file.key); try { diff --git a/web/src/routes/[handle]/[repo]/commit/[ref]/+page.ts b/web/src/routes/[handle]/[repo]/commit/[ref]/+page.ts index 8e5dd2ae5..771776cb2 100644 --- a/web/src/routes/[handle]/[repo]/commit/[ref]/+page.ts +++ b/web/src/routes/[handle]/[repo]/commit/[ref]/+page.ts @@ -10,9 +10,9 @@ import { cappedFetch, isDiffTooLarge, loadDiff, - type PullDiffDeps, - type PullDiffSpec -} from "$lib/api/pullDiff"; + type RepoDiffDeps, + type RepoDiffSpec +} from "$lib/api/repoDiff"; import { withAuthorHandles } from "$lib/api/repoIndex"; import type { Did } from "@atcute/lexicons/syntax"; @@ -48,7 +48,7 @@ export const load: PageLoad = async (event) => { }) ); } - const spec: PullDiffSpec | undefined = parentRef + const spec: RepoDiffSpec | undefined = parentRef ? { kind: "diff", repo: repoDid, version: { base: parentRef, head: wire.oid } } : undefined; const git = knotMirrorTarget(parent.publicConfig, { repoDid }, event.fetch); @@ -56,7 +56,7 @@ export const load: PageLoad = async (event) => { // through, so above the configured byte cap the body is abandoned mid-read // and the page refetches the diff from the browser instead const maxBytes = (await event.parent()).publicConfig.ssrDiffMaxBytes; - const diffDeps: PullDiffDeps = { + const diffDeps: RepoDiffDeps = { ctx: !browser && maxBytes > 0 ? { ...git.ctx, fetch: cappedFetch(git.ctx.fetch, maxBytes) } @@ -64,7 +64,7 @@ export const load: PageLoad = async (event) => { git }; let diff; - let diffSpec: PullDiffSpec | undefined; + let diffSpec: RepoDiffSpec | undefined; try { diff = spec ? await loadDiff(diffDeps, spec) : undefined; } catch (cause) { diff --git a/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte b/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte index 86fafcd80..0be7ebbcb 100644 --- a/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte +++ b/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte @@ -32,7 +32,7 @@ import { gitTarget } from "$lib/api/gitclient"; import { getPatchStream } from "$lib/api/patchStream"; import { getRepoByRepoDid } from "$lib/api/records"; - import { loadDiff, type PullDiffDeps, type PullDiffSpec } from "$lib/api/pullDiff"; + import { loadDiff, type RepoDiffDeps, type RepoDiffSpec } from "$lib/api/repoDiff"; import { fileAnchor } from "$lib/components/repo/fileAnchor.svelte"; import type { PullView as PullRouteView } from "$lib/api/pullRoute"; import { formatPatchUrl, getBranch, getMergeBase } from "$lib/api/knotmirror"; @@ -52,7 +52,7 @@ import Button from "$lib/components/ui/Button.svelte"; import Spinner from "$lib/components/ui/Spinner.svelte"; import ErrorAlert from "$lib/components/ui/Error.svelte"; - import PullDiff from "$lib/components/repo/pulls/PullDiff.svelte"; + import DiffView from "$lib/components/repo/DiffView.svelte"; import PullDiscussion from "$lib/components/repo/pulls/PullDiscussion.svelte"; import PullReviewCommentForm from "$lib/components/repo/pulls/PullReviewCommentForm.svelte"; import type { Range } from "$lib/components/ui/RangeSelector.svelte"; @@ -271,7 +271,7 @@ : view.to.head ); - const diffSpec = $derived( + const diffSpec = $derived( view.mode === "diff" ? { kind: "diff", @@ -287,7 +287,7 @@ } ); - const diffDeps = $derived({ + const diffDeps = $derived({ ctx: createBobbinClient({ serviceUrl: data.publicConfig.bobbinUrl, fetch: globalThis.fetch @@ -314,7 +314,7 @@ // Lookup rather than effect to avoid an undefined frame triggering duplicate fetches. const patch = $derived(browser && patchUrl ? getPatchStream(patchUrl) : undefined); - let pullDiff = $state<{ jumpToFile: (path: string) => number | undefined }>(); + let diffView = $state<{ jumpToFile: (path: string) => number | undefined }>(); const conflictAnchor = (filename: string) => diff.data?.files.some((file) => file.name === filename) ? fileAnchor(filename) : undefined; @@ -324,7 +324,7 @@ // a hash on the page we are already on: nothing to resolve, nothing to load // eslint-disable-next-line svelte/no-navigation-without-resolve replaceState(anchor, page.state); - pullDiff?.jumpToFile(filename); + diffView?.jumpToFile(filename); }; let discussionOpen = $state(true); @@ -674,7 +674,7 @@ {#if pull.versions.length} - {/if}