aboutsummaryrefslogtreecommitdiff
path: root/source/library/state/history.svelte.ts
blob: 2726283ed4e9d65f729dfcff5e0ae1001f6c7dc3 (plain) (blame)
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
82
83
84
85
86
87
88
89
90
91
92
93
94
/*** UTILITY ------------------------------------------ ***/

import { evict } from "./history-logic.ts";
import type { Storage } from "./storage.ts";

const MAX_ENTRIES = 100;
const STORAGE_KEY = "history";

/*** EXPORT ------------------------------------------- ***/

export type HistoryEntry = {
  favorite: boolean;
  headers: string;
  id: string;
  operationName: string | null;
  query: string;
  timestamp: number;
  title: string;
  variables: string;
};

export type HistoryInput = {
  headers: string;
  operationName: string | null;
  query: string;
  title: string;
  variables: string;
};

export class HistoryStore {
  entries = $state<HistoryEntry[]>([]);

  #storage: Storage;

  constructor(storage: Storage) {
    this.#storage = storage;

    const restored = storage.get<HistoryEntry[]>(STORAGE_KEY);

    if (Array.isArray(restored))
      this.entries = restored.map((e) => ({
        favorite: Boolean(e.favorite),
        headers: e.headers ?? "{}",
        id: e.id,
        operationName: e.operationName ?? null,
        query: e.query ?? "",
        timestamp: e.timestamp ?? Date.now(),
        title: e.title ?? "untitled",
        variables: e.variables ?? "{}"
      }));
  }

  add(input: HistoryInput) {
    const entry: HistoryEntry = {
      favorite: false,
      headers: input.headers,
      id: crypto.randomUUID(),
      operationName: input.operationName,
      query: input.query,
      timestamp: Date.now(),
      title: input.title,
      variables: input.variables
    };

    this.entries = [entry, ...this.entries];
    this.#evict();
  }

  clear() {
    this.entries = this.entries.filter((e) => e.favorite);
  }

  favorite(id: string) {
    const entry = this.entries.find((e) => e.id === id);

    if (entry)
      entry.favorite = !entry.favorite;
  }

  persist() {
    this.#storage.set<HistoryEntry[]>(STORAGE_KEY, this.entries);
  }

  remove(id: string) {
    this.entries = this.entries.filter((e) => e.id !== id);
  }

  #evict() {
    this.entries = evict(this.entries, MAX_ENTRIES);
  }
}