Skip to content
File

Blob: src/client/lib/api/bookmarks.ts

typescript67 lines
1import { D1_BOOKMARK_HEADER } from "@/shared/d1";
2import { D1_BOOKMARKS_KEY, type ApiRequestOptions } from "./shared";
3 
4export function getInboxBookmarkScope(address: string) {
5 return `inbox:${address}`;
6}
7 
8function parseStoredBookmarks() {
9 try {
10 const raw = localStorage.getItem(D1_BOOKMARKS_KEY);
11 if (!raw) {
12 return {} as Record<string, string>;
13 }
14 
15 const parsed = JSON.parse(raw);
16 if (!parsed || typeof parsed !== "object") {
17 return {} as Record<string, string>;
18 }
19 
20 return Object.fromEntries(
21 Object.entries(parsed).filter(
22 (entry): entry is [string, string] => typeof entry[1] === "string" && entry[1].length > 0,
23 ),
24 );
25 } catch {
26 return {} as Record<string, string>;
27 }
28}
29 
30function writeStoredBookmarks(bookmarks: Record<string, string>) {
31 localStorage.setItem(D1_BOOKMARKS_KEY, JSON.stringify(bookmarks));
32 return bookmarks;
33}
34 
35export function getStoredBookmark(scope: string) {
36 return parseStoredBookmarks()[scope] ?? null;
37}
38 
39export function setStoredBookmark(scope: string, bookmark: string) {
40 const next = parseStoredBookmarks();
41 next[scope] = bookmark;
42 writeStoredBookmarks(next);
43}
44 
45export function clearStoredBookmark(scope: string) {
46 const next = parseStoredBookmarks();
47 if (!(scope in next)) {
48 return;
49 }
50 
51 delete next[scope];
52 writeStoredBookmarks(next);
53}
54 
55export function applyResponseBookmark(
56 response: Response,
57 options?: Pick<ApiRequestOptions, "bookmarkScope" | "onBookmark">,
58) {
59 const bookmark = response.headers.get(D1_BOOKMARK_HEADER)?.trim() || null;
60 
61 if (bookmark && options?.bookmarkScope) {
62 setStoredBookmark(options.bookmarkScope, bookmark);
63 }
64 
65 options?.onBookmark?.(bookmark);
66}