aboutsummaryrefslogtreecommitdiff
path: root/Hutch/Views/Lookup/UserProfileViewModel.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-05-06 20:41:49 -0500
committerChristian Cleberg <[email protected]>2026-05-06 20:41:49 -0500
commit205cf2687ce48f3d004792ff223422a86cc6bdbc (patch)
tree7edb78cede354e79aa8abd764ed9c5047e0ee168 /Hutch/Views/Lookup/UserProfileViewModel.swift
parent57e4f34b4613c09beb0cb757ac2ba2b43cc04daf (diff)
downloadhutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.tar.gz
hutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.tar.bz2
hutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.zip
feat(cache): persist read-only API responsesv3.3.1
Add a bounded stale-while-revalidate cache at the Sourcehut API boundary with stable keys, centralized TTLs, request coalescing, payload hashing, and LRU disk pruning. Cache high-value read-only repo, build, ticket, project, profile, paste, and Home/Work Queue data while keeping mutations network-only and invalidating related prefixes after successful writes. Add focused cache tests and implementation notes.
Diffstat (limited to 'Hutch/Views/Lookup/UserProfileViewModel.swift')
-rw-r--r--Hutch/Views/Lookup/UserProfileViewModel.swift20
1 files changed, 14 insertions, 6 deletions
diff --git a/Hutch/Views/Lookup/UserProfileViewModel.swift b/Hutch/Views/Lookup/UserProfileViewModel.swift
index 0e503ce..c482d6f 100644
--- a/Hutch/Views/Lookup/UserProfileViewModel.swift
+++ b/Hutch/Views/Lookup/UserProfileViewModel.swift
@@ -49,13 +49,17 @@ final class UserProfileViewModel {
defer { isLoadingRepositories = false }
do {
- let result = try await client.execute(
+ let cached = try await client.executeCached(
service: .git,
query: Self.repositoriesQuery,
variables: ["owner": ownerUsername],
- responseType: UserRepositoriesResponse.self
+ responseType: UserRepositoriesResponse.self,
+ cacheKey: APICacheKeys.userRepositories(owner: ownerUsername),
+ resourceType: .userProfile,
+ ttl: APICacheTTLs.userProfile,
+ policy: .cacheFirstThenRefresh
)
- repositories = result.user.repositories.results.map { $0.repositorySummary(service: .git) }
+ repositories = cached.value.user.repositories.results.map { $0.repositorySummary(service: .git) }
} catch {
repositoriesError = error.userFacingMessage
}
@@ -78,13 +82,17 @@ final class UserProfileViewModel {
defer { isLoadingTrackers = false }
do {
- let result = try await client.execute(
+ let cached = try await client.executeCached(
service: .todo,
query: Self.trackersQuery,
variables: ["owner": ownerUsername],
- responseType: UserTrackersResponse.self
+ responseType: UserTrackersResponse.self,
+ cacheKey: APICacheKeys.userTrackers(owner: ownerUsername),
+ resourceType: .userProfile,
+ ttl: APICacheTTLs.userProfile,
+ policy: .cacheFirstThenRefresh
)
- trackers = result.user.trackers.results
+ trackers = cached.value.user.trackers.results
} catch {
trackersError = error.userFacingMessage
}