File size: 2,131 Bytes
7450ebd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import type { Project } from "$lib/types.js";
import { PersistedState } from "runed";
import { session } from "./session.svelte";

const ls_key = "checkpoints";

type Checkpoint = {
	id: string;
	timestamp: string;
	projectState: Project;
	favorite?: boolean;
};

class Checkpoints {
	#checkpoints = new PersistedState<Record<Project["id"], Checkpoint[]>>(
		ls_key,
		{},
		{
			serializer: {
				serialize: JSON.stringify,
				deserialize: v => {
					return JSON.parse(v);
				},
			},
		}
	);

	for(projectId: Project["id"]) {
		return (
			this.#checkpoints.current[projectId]?.toSorted((a, b) => {
				return b.timestamp.localeCompare(a.timestamp);
			}) ?? []
		);
	}

	commit(projectId: Project["id"]) {
		const project = session.$.projects.find(p => p.id == projectId);
		if (!project) return;
		const prev: Checkpoint[] = this.#checkpoints.current[projectId] ?? [];
		this.#checkpoints.current[projectId] = [
			...prev,
			{ projectState: project, timestamp: new Date().toLocaleString(), id: crypto.randomUUID() },
		];
	}

	restore(projectId: Project["id"], checkpoint: Checkpoint) {
		const project = session.$.projects.find(p => p.id == projectId);
		if (!project) return;

		session.$.activeProjectId = projectId;
		session.project = checkpoint.projectState;
	}

	toggleFavorite(projectId: Project["id"], checkpoint: Checkpoint) {
		const prev: Checkpoint[] = this.#checkpoints.current[projectId] ?? [];
		this.#checkpoints.current[projectId] = prev.map(c => {
			if (c.id == checkpoint.id) {
				return { ...c, favorite: !c.favorite };
			}
			return c;
		});
	}

	delete(projectId: Project["id"], checkpoint: Checkpoint) {
		const prev: Checkpoint[] = this.#checkpoints.current[projectId] ?? [];
		this.#checkpoints.current[projectId] = prev.filter(c => c.id != checkpoint.id);
	}

	clear(projectId: Project["id"]) {
		this.#checkpoints.current[projectId] = [];
	}

	migrate(from: Project["id"], to: Project["id"]) {
		const fromArr = this.#checkpoints.current[from] ?? [];
		this.#checkpoints.current[to] = [...fromArr];
		this.#checkpoints.current[from] = [];
	}
}

export const checkpoints = new Checkpoints();