diff options
Diffstat (limited to 'source/library/state/history.svelte.ts')
| -rw-r--r-- | source/library/state/history.svelte.ts | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/source/library/state/history.svelte.ts b/source/library/state/history.svelte.ts new file mode 100644 index 0000000..2726283 --- /dev/null +++ b/source/library/state/history.svelte.ts @@ -0,0 +1,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); + } +} |