summaryrefslogtreecommitdiff
path: root/Hutch/Networking/APICacheKeys.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/Networking/APICacheKeys.swift
parent57e4f34b4613c09beb0cb757ac2ba2b43cc04daf (diff)
downloadhutch-3.3.1.tar.gz
hutch-3.3.1.tar.bz2
hutch-3.3.1.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/Networking/APICacheKeys.swift')
-rw-r--r--Hutch/Networking/APICacheKeys.swift43
1 files changed, 43 insertions, 0 deletions
diff --git a/Hutch/Networking/APICacheKeys.swift b/Hutch/Networking/APICacheKeys.swift
index 5e57a51..d0cffa6 100644
--- a/Hutch/Networking/APICacheKeys.swift
+++ b/Hutch/Networking/APICacheKeys.swift
@@ -51,6 +51,14 @@ enum APICacheKeys {
make([SRHTService.todo.rawValue, "tracker-labels", "tracker:\(trackerRid)"])
}
+ static func trackers(cursor: String? = nil) -> String {
+ make([SRHTService.todo.rawValue, "trackers", cursor.map { "cursor:\($0)" }])
+ }
+
+ static func tickets(trackerRid: String, cursor: String? = nil) -> String {
+ make([SRHTService.todo.rawValue, "tickets", "tracker:\(trackerRid)", cursor.map { "cursor:\($0)" }])
+ }
+
static func builds(cursor: String? = nil, filter: String? = nil) -> String {
make([SRHTService.builds.rawValue, "jobs", cursor.map { "cursor:\($0)" }, filter.map { "filter:\($0)" }])
}
@@ -71,6 +79,37 @@ enum APICacheKeys {
make([SRHTService.todo.rawValue, "user-trackers", normalize(owner), cursor.map { "cursor:\($0)" }])
}
+ static func projects(cursor: String? = nil) -> String {
+ make([SRHTService.hub.rawValue, "projects", cursor.map { "cursor:\($0)" }])
+ }
+
+ static func projectDetail(rid: String, mailingListsCursor: String? = nil, sourcesCursor: String? = nil, trackersCursor: String? = nil) -> String {
+ make([
+ SRHTService.hub.rawValue,
+ "project",
+ "rid:\(rid)",
+ mailingListsCursor.map { "ml:\($0)" },
+ sourcesCursor.map { "src:\($0)" },
+ trackersCursor.map { "trk:\($0)" }
+ ])
+ }
+
+ static func homeJobs(actor: String) -> String {
+ make(["home", "jobs", normalize(actor)])
+ }
+
+ static func homeTrackerTickets(owner: String, tracker: String) -> String {
+ make(["home", "tickets", normalize(owner), normalize(tracker)])
+ }
+
+ static func inboxSubscriptions(cursor: String? = nil) -> String {
+ make([SRHTService.lists.rawValue, "subscriptions", cursor.map { "cursor:\($0)" }])
+ }
+
+ static func inboxThreads(listRid: String, cursor: String? = nil) -> String {
+ make([SRHTService.lists.rawValue, "threads", "list:\(listRid)", cursor.map { "cursor:\($0)" }])
+ }
+
static func pasteList(cursor: String? = nil) -> String {
make([SRHTService.paste.rawValue, "pastes", cursor.map { "cursor:\($0)" }])
}
@@ -102,4 +141,8 @@ enum APICacheTTLs {
static let movingRefFileContent: TimeInterval = 10 * 60
static let userProfile: TimeInterval = 30 * 60
static let status: TimeInterval = 5 * 60
+ static let homeDashboard: TimeInterval = 2 * 60
+ static let inboxSummary: TimeInterval = 2 * 60
+ static let projectList: TimeInterval = 10 * 60
+ static let projectDetail: TimeInterval = 10 * 60
}