types.ts RawHistoryFolder
1// ═══════════════════════════════════════════════════════════════════════════════
2// Homepage TypeScript Types
3// Mirrors Go models from internal/db/models.go and related query files
4// ═══════════════════════════════════════════════════════════════════════════════
5
6import type { Component } from 'svelte';
7
8// ─────────────────────────────────────────────────────────────────────────────
9// History Types
10// ─────────────────────────────────────────────────────────────────────────────
11
12export interface HistoryEntry {
13 id: number;
14 url: string;
15 title: string | null;
16 favicon_url: string | null;
17 visit_count: number;
18 last_visited: string;
19 created_at: string;
20}
21
22export interface TimelineGroup {
23 date: string; // YYYY-MM-DD
24 label: string; // "Today", "Yesterday", "Dec 5", etc.
25 entries: HistoryEntry[];
26}
27
28export interface HistoryStats {
29 total_entries: number;
30 total_visits: number;
31 unique_days: number;
32}
33
34export interface DomainStat {
35 domain: string;
36 page_count: number;
37 total_visits: number;
38 last_visit: string;
39}
40
41export interface DailyVisitCount {
42 day: string;
43 entries: number;
44 visits: number;
45}
46
47export interface HourlyDistribution {
48 hour: number;
49 visit_count: number;
50}
51
52// ─────────────────────────────────────────────────────────────────────────────
53// Favorites Types
54// ─────────────────────────────────────────────────────────────────────────────
55
56export interface Favorite {
57 id: number;
58 url: string;
59 title: string | null;
60 favicon_url: string | null;
61 position: number;
62 created_at: string;
63 updated_at: string;
64 folder_id: number | null;
65 shortcut_key: number | null; // 1-9
66 tags?: Tag[]; // Populated via join
67}
68
69export interface Folder {
70 id: number;
71 name: string;
72 icon: string | null;
73 position: number;
74 created_at: string;
75}
76
77export interface Tag {
78 id: number;
79 name: string;
80 color: string; // Hex color like #6b7280
81 created_at: string;
82}
83
84export interface TagAssignment {
85 favorite_id: number;
86 tag_id: number;
87}
88
89// ─────────────────────────────────────────────────────────────────────────────
90// Analytics Types
91// ─────────────────────────────────────────────────────────────────────────────
92
93// Matches Go HistoryAnalytics struct (flat structure)
94export interface Analytics {
95 total_entries: number;
96 total_visits: number;
97 unique_days: number;
98 top_domains: DomainStat[];
99 daily_visits: DailyVisitCount[];
100 hourly_distribution: HourlyDistribution[];
101}
102
103// ─────────────────────────────────────────────────────────────────────────────
104// UI State Types
105// ─────────────────────────────────────────────────────────────────────────────
106
107export type PanelType = 'history' | 'favorites' | 'analytics';
108
109export type HistoryCleanupRange = 'hour' | 'day' | 'week' | 'month' | 'all';
110
111export interface CommandPaletteItem {
112 id: string;
113 label: string;
114 description?: string;
115 icon?: Component | string;
116 action: () => void;
117 shortcut?: string;
118}
119
120export interface KeyboardShortcut {
121 key: string;
122 description: string;
123 action: () => void;
124 context?: 'global' | 'history' | 'favorites' | 'command-palette';
125}
126
127// ─────────────────────────────────────────────────────────────────────────────
128// Message Types (WebKit Bridge)
129// ─────────────────────────────────────────────────────────────────────────────
130
131export type MessageType =
132 // Folders
133 | 'folder_list'
134 | 'folder_create'
135 | 'folder_update'
136 | 'folder_delete'
137 // Tags
138 | 'tag_list'
139 | 'tag_create'
140 | 'tag_update'
141 | 'tag_delete'
142 | 'tag_assign'
143 | 'tag_remove'
144 // History
145 | 'history_timeline'
146 | 'history_search_fts'
147 | 'history_analytics'
148 | 'history_domain_stats'
149 | 'history_delete_entry'
150 | 'history_delete_range'
151 | 'history_clear_all'
152 | 'history_delete_domain'
153 // Favorites
154 | 'favorite_list'
155 | 'favorite_set_shortcut'
156 | 'favorite_get_by_shortcut'
157 | 'favorite_set_folder';
158
159export interface Message<T = unknown> {
160 type: MessageType;
161 requestId?: string;
162 payload?: T;
163}
164
165export interface MessageResponse<T = unknown> {
166 success: boolean;
167 data?: T;
168 error?: string;
169}
170
171// ─────────────────────────────────────────────────────────────────────────────
172// Request/Response Payloads
173// ─────────────────────────────────────────────────────────────────────────────
174
175// History
176export interface HistoryTimelineRequest {
177 limit?: number;
178 offset?: number;
179}
180
181export interface HistorySearchRequest {
182 query: string;
183 limit?: number;
184}
185
186export interface HistoryDeleteRangeRequest {
187 range: HistoryCleanupRange;
188}
189
190export interface HistoryDeleteDomainRequest {
191 domain: string;
192}
193
194// Folders
195export interface FolderCreateRequest {
196 name: string;
197 icon?: string;
198}
199
200export interface FolderUpdateRequest {
201 id: number;
202 name: string;
203 icon?: string;
204}
205
206// Tags
207export interface TagCreateRequest {
208 name: string;
209 color?: string;
210}
211
212export interface TagUpdateRequest {
213 id: number;
214 name?: string;
215 color?: string;
216}
217
218export interface TagAssignRequest {
219 favorite_id: number;
220 tag_id: number;
221}
222
223// Favorites
224export interface FavoriteShortcutRequest {
225 favorite_id: number;
226 shortcut_key: number; // 1-9
227}
228
229export interface FavoriteFolderRequest {
230 favorite_id: number;
231 folder_id: number | null;
232}