Migrate all IPC call sites to typed tauri-specta commands.*
🏗️ Build and Test JellyTau / Run Tests (pull_request) Successful in 4m39s
Traceability Validation / Check Requirement Traces (pull_request) Failing after 36s
🏗️ Build and Test JellyTau / Build Android APK (pull_request) Failing after 1m57s

Replace the remaining ~155 untyped invoke() calls across stores, services,
components, and routes with the generated commands.* wrappers from
$lib/api/bindings, so every IPC call is compile-time-checked against the
command signatures.

- Register repository_get_subtitle_url and repository_get_video_download_url
  in specta_builder() and the invoke_handler; regenerate bindings.ts.
- Source duplicated wire types (AutoplaySettings, CacheConfig, Session,
  ConnectivityStatus, audio/video settings, etc.) from bindings.
- Fix two bugs surfaced by the typed wrappers:
  - VideoDownloadButton passed an un-awaited Promise as the stream URL.
  - setAutoplaySettings omitted the required userId argument.
- Update unit tests asserting the old invoke(name, args) shape.
- Remove the five param-naming guard tests; the compiler and codegen now
  enforce what they checked.

svelte-check: 0 errors. vitest: green. cargo test --lib: green.
This commit is contained in:
2026-06-21 08:47:04 +02:00
parent 14e9d7e03a
commit d01c2aab9f
47 changed files with 456 additions and 2119 deletions
+7 -16
View File
@@ -1,8 +1,8 @@
// Image cache service - Handles lazy caching of thumbnails with LRU eviction
// TRACES: UR-007 | DR-016
import { invoke } from "@tauri-apps/api/core";
import { convertFileSrc } from "@tauri-apps/api/core";
import { commands } from "$lib/api/bindings";
/**
* Statistics about the thumbnail cache
@@ -38,11 +38,7 @@ export async function getCachedImageUrl(
// Try to get cached version
try {
const cachedPath = await invoke<string | null>("thumbnail_get_cached", {
itemId,
imageType,
tag,
});
const cachedPath = await commands.thumbnailGetCached(itemId, imageType, tag);
if (cachedPath) {
// Convert file path to asset URL for Tauri
@@ -62,12 +58,7 @@ export async function getCachedImageUrl(
const serverImageUrl = `${serverUrl}/Items/${itemId}/Images/${imageType}?${params.toString()}`;
// Trigger background caching (fire and forget)
invoke("thumbnail_save", {
itemId,
imageType,
tag,
url: serverImageUrl,
}).catch((e) => {
commands.thumbnailSave(itemId, imageType, tag, serverImageUrl).catch((e) => {
// Silently fail - caching is best-effort
console.debug("Background thumbnail cache failed:", e);
});
@@ -80,7 +71,7 @@ export async function getCachedImageUrl(
* Get thumbnail cache statistics
*/
export async function getCacheStats(): Promise<ImageCacheStats> {
return invoke("thumbnail_get_stats");
return commands.thumbnailGetStats();
}
/**
@@ -89,14 +80,14 @@ export async function getCacheStats(): Promise<ImageCacheStats> {
* @param limitBytes - The maximum cache size in bytes (0 = unlimited)
*/
export async function setCacheLimit(limitBytes: number): Promise<void> {
return invoke("thumbnail_set_limit", { limitBytes });
await commands.thumbnailSetLimit(limitBytes);
}
/**
* Clear all cached thumbnails
*/
export async function clearCache(): Promise<void> {
return invoke("thumbnail_clear_cache");
await commands.thumbnailClearCache();
}
/**
@@ -105,7 +96,7 @@ export async function clearCache(): Promise<void> {
* @param itemId - The Jellyfin item ID
*/
export async function deleteItemCache(itemId: string): Promise<void> {
return invoke("thumbnail_delete_item", { itemId });
await commands.thumbnailDeleteItem(itemId);
}
/**