changes.ts

 1import { writable } from 'svelte/store';
 2import type { ChangeInfo, ChangeStack } from '$lib/types/index';
 3import { loadFiles, loadAllDiffs } from './files.ts';
 4
 5export type StackResponse = ChangeStack & { vcs?: string; error?: string };
 6
 7export const changes = writable<ChangeInfo[]>([]);
 8export const mainChange = writable<ChangeStack['main']>(null);
 9export const currentChange = writable<string | null>(null);
10/** Signature of the last applied stack, used to avoid redundant reloads. */
11export const lastStackSignature = writable('');
12
13function apply(data: StackResponse) {
14	if (!Array.isArray(data.changes)) return;
15	changes.set(data.changes);
16	mainChange.set(data.main ?? null);
17	currentChange.set(data.current ?? null);
18	lastStackSignature.set(stackSignature(data));
19}
20
21export async function loadChanges(): Promise<StackResponse | null> {
22	try {
23		const res = await fetch('/api/changes');
24		const data = (await res.json()) as StackResponse;
25		apply(data);
26		return data;
27	} catch {
28		return null;
29	}
30}
31
32async function postChange(action: 'select' | 'approve', changeId?: string): Promise<void> {
33	const res = await fetch('/api/changes', {
34		method: 'POST',
35		headers: { 'Content-Type': 'application/json' },
36		body: JSON.stringify({ action, changeId })
37	});
38	const data = (await res.json()) as StackResponse;
39	if (data.error) throw new Error(data.error);
40	apply(data);
41	await loadFiles();
42	await loadAllDiffs();
43}
44
45export async function selectChange(changeId: string): Promise<void> {
46	await postChange('select', changeId);
47}
48
49export async function approveChange(changeId?: string): Promise<void> {
50	await postChange('approve', changeId);
51}
52
53/** Signature used to detect whether the stack changed enough to reload diffs. */
54export function stackSignature(data: StackResponse | null): string {
55	if (!data || !Array.isArray(data.changes)) return '';
56	return JSON.stringify([
57		data.main?.commitId ?? null,
58		data.current ?? null,
59		data.changes.map((c) => [c.changeId, c.commitId])
60	]);
61}