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}