fix(types): clear web/src type and lint debt with real types
tsc --noEmit and oxlint web/src are now both clean; vp check passes.
- htmx: one canonical Htmx interface in shims.d.ts (ajax/process/trigger
per the htmx 2.x API). alpine.ts had a second, conflicting Window.htmx
declaration (TS2717) — removed; bookPicker/collections lose their
(window as any) escapes now that Window.htmx is properly typed.
- tsconfig lib ES2020 -> ES2021 + DOM.Iterable: replaceAll exists
(escapeHtml) and for..of over querySelectorAll results is legal.
Type-checking only — vite emits at esnext regardless.
- custom-section-builder: selectedBooks holds identity fields only;
typed as Pick<BookInfo, ...> instead of forcing partial API shapes.
The API-critical BookInfo contract is untouched.
- toast: real bug found by the type system — setup.ts passes 'warning'
but getToastConfig had no entry, so the warning toast threw TypeError
at runtime instead of displaying. Added the type + config. Uses
bg-yellow-500 (verified present in scanned templates => generated by
Tailwind); the one intentional behavior change in this commit.
- book-detail: instanceof narrowing replaces an as-cast; unused
AnnotationSource import removed.
- password_validation: explicit HTMLElement | null for the checklist
list (querySelector('ul') infers HTMLUListElement, conflicting with
the container-as-list branch).
- stats: tooltip parsed value typed via annotation (bar=scalar,
line={x,y}); dead getActiveRange() removed (was already tree-shaken
out of every bundle).
- library-switcher: onSwitch honestly typed void | Promise<void>
(series.ts passes a sync navigator).
- 20 unused catch bindings converted to optional catch binding.
Verification: fresh build is byte-reproducible; every chunk is
identical to the pre-fix build except main.js (instanceof narrowing,
regex fix, stats refactor), reader.js (destructure), and the shared
storage chunk (renamed — carries toast.ts). reader/main diffs audited
hunk-by-hunk against the intended edits.
This commit is contained in:
1 parent
77cd268f4e
commit
d7d1495753
14 files changed
+70
-60
No files matched your search
+16
-16
@@ -187,7 +187,7 @@ async function loadFontBlobUrls(): Promise<void> {
|
||||
const blob = await resp.blob();
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
return { key: f.url, blobUrl };
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
return { key: f.url, blobUrl: f.url };
|
||||
}
|
||||
}),
|
||||
@@ -1533,7 +1533,7 @@ document.addEventListener("alpine:init", () => {
|
||||
async adjustFinalize() {
|
||||
const ctx = this.adjustContext;
|
||||
if (!ctx) return;
|
||||
const { index, doc, range, id } = ctx;
|
||||
const { index, range, id } = ctx;
|
||||
const text = range.toString().replace(/\s+/g, " ").trim();
|
||||
this.cancelAdjust();
|
||||
if (!text) {
|
||||
@@ -2452,7 +2452,7 @@ document.addEventListener("alpine:init", () => {
|
||||
positionLabel: r.position ?? "",
|
||||
}));
|
||||
}
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* annotations are non-critical; leave lists as-is */
|
||||
}
|
||||
},
|
||||
@@ -2523,7 +2523,7 @@ document.addEventListener("alpine:init", () => {
|
||||
}
|
||||
}
|
||||
this.hideSelectionPopover();
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore highlight errors */
|
||||
}
|
||||
},
|
||||
@@ -2590,7 +2590,7 @@ document.addEventListener("alpine:init", () => {
|
||||
// Explicit saves (the Save button) close the whole popover; color
|
||||
// tweaks made while the note editor is open keep everything open.
|
||||
if (!keepNoteOpen) this.hideSelectionPopover();
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore highlight errors */
|
||||
}
|
||||
},
|
||||
@@ -2615,7 +2615,7 @@ document.addEventListener("alpine:init", () => {
|
||||
});
|
||||
}
|
||||
this.hideSelectionPopover();
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore highlight errors */
|
||||
}
|
||||
},
|
||||
@@ -2839,7 +2839,7 @@ document.addEventListener("alpine:init", () => {
|
||||
});
|
||||
if (!resp.ok) return;
|
||||
await this.refreshAnnotations();
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore note errors */
|
||||
}
|
||||
},
|
||||
@@ -2882,7 +2882,7 @@ document.addEventListener("alpine:init", () => {
|
||||
note.positionLabel = row.position ?? note.positionLabel;
|
||||
note.editOpen = false;
|
||||
note.editText = "";
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* note errors are non-critical */
|
||||
}
|
||||
},
|
||||
@@ -2897,7 +2897,7 @@ document.addEventListener("alpine:init", () => {
|
||||
if (resp.ok || resp.status === 204) {
|
||||
this.noteItems = this.noteItems.filter((n) => n.id !== id);
|
||||
}
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore note errors */
|
||||
}
|
||||
},
|
||||
@@ -2928,7 +2928,7 @@ document.addEventListener("alpine:init", () => {
|
||||
page: typeof page === "number" ? page : 0,
|
||||
percentage: typeof pct === "number" ? pct : 0,
|
||||
};
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
@@ -3017,7 +3017,7 @@ document.addEventListener("alpine:init", () => {
|
||||
});
|
||||
this.lastSyncedCfi = cfi || "";
|
||||
this.lastSyncedFraction = fraction;
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
// silent fail — progress save is non-critical
|
||||
}
|
||||
},
|
||||
@@ -3658,7 +3658,7 @@ document.addEventListener("alpine:init", () => {
|
||||
cfi: r.cfi_position?.String ?? r.cfi_position ?? "",
|
||||
page: r.page_number != null ? (r.page_number?.Int32 ?? r.page_number) : null,
|
||||
}));
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* leave the existing list on fetch failure */
|
||||
}
|
||||
},
|
||||
@@ -3696,7 +3696,7 @@ document.addEventListener("alpine:init", () => {
|
||||
await this.refreshBookmarks();
|
||||
showToast(`Bookmark added — ${this.progressText || "current position"}`, "success", 2500);
|
||||
}
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* network failures surface via the toast fetch interceptor */
|
||||
}
|
||||
},
|
||||
@@ -3711,7 +3711,7 @@ document.addEventListener("alpine:init", () => {
|
||||
if (resp.ok || resp.status === 204) {
|
||||
this.bookmarkItems = this.bookmarkItems.filter((b) => b.id !== id);
|
||||
}
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
/* ignore bookmark errors for now */
|
||||
}
|
||||
},
|
||||
@@ -3740,7 +3740,7 @@ document.addEventListener("alpine:init", () => {
|
||||
bookmark.title = title;
|
||||
}
|
||||
bookmark.renameOpen = false;
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
bookmark.renameOpen = false;
|
||||
}
|
||||
},
|
||||
@@ -3905,7 +3905,7 @@ document.addEventListener("alpine:init", () => {
|
||||
const data = await resp.json();
|
||||
this.readingSpeedPpm = data.pages_per_minute || 0;
|
||||
}
|
||||
} catch (_e) {
|
||||
} catch {
|
||||
this.readingSpeedPpm = 0;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function loadSettings(): Promise<ReaderSettings> {
|
||||
const settings = await response.json();
|
||||
localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(settings));
|
||||
return settings;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
const local = localStorage.getItem(LOCALSTORAGE_KEY);
|
||||
return local ? JSON.parse(local) : getDefaultSettings();
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export async function saveSettings(settings: Partial<ReaderSettings>): Promise<v
|
||||
body: JSON.stringify(settings),
|
||||
});
|
||||
localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(updated));
|
||||
} catch (error) {
|
||||
} catch {
|
||||
localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(updated));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user