hyperoslo/Cache
:package: Nothing but Cache.
Slowing — last commit 8mo ago
worst of 4 axesnon-standard license (Other); no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
last commit was 8mo ago; no CI workflows detected
- ✓Last commit 8mo ago
- ✓24+ active contributors
- ✓Other licensed
Show 5 more →Show less
- ✓Tests present
- ⚠Slowing — last commit 8mo ago
- ⚠Concentrated ownership — top contributor handles 54% of recent commits
- ⚠Non-standard license (Other) — review terms
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/hyperoslo/cache)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/hyperoslo/cache on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: hyperoslo/Cache
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/hyperoslo/Cache shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Slowing — last commit 8mo ago
- Last commit 8mo ago
- 24+ active contributors
- Other licensed
- Tests present
- ⚠ Slowing — last commit 8mo ago
- ⚠ Concentrated ownership — top contributor handles 54% of recent commits
- ⚠ Non-standard license (Other) — review terms
- ⚠ No CI workflows detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live hyperoslo/Cache
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/hyperoslo/Cache.
What it runs against: a local clone of hyperoslo/Cache — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in hyperoslo/Cache | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 283 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of hyperoslo/Cache. If you don't
# have one yet, run these first:
#
# git clone https://github.com/hyperoslo/Cache.git
# cd Cache
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of hyperoslo/Cache and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "hyperoslo/Cache(\\.git)?\\b" \\
&& ok "origin remote is hyperoslo/Cache" \\
|| miss "origin remote is not hyperoslo/Cache (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Source/Shared/Storage/Storage.swift" \\
&& ok "Source/Shared/Storage/Storage.swift" \\
|| miss "missing critical file: Source/Shared/Storage/Storage.swift"
test -f "Source/Shared/Storage/HybridStorage.swift" \\
&& ok "Source/Shared/Storage/HybridStorage.swift" \\
|| miss "missing critical file: Source/Shared/Storage/HybridStorage.swift"
test -f "Source/Shared/Library/Transformer.swift" \\
&& ok "Source/Shared/Library/Transformer.swift" \\
|| miss "missing critical file: Source/Shared/Library/Transformer.swift"
test -f "Source/Shared/Configuration/DiskConfig.swift" \\
&& ok "Source/Shared/Configuration/DiskConfig.swift" \\
|| miss "missing critical file: Source/Shared/Configuration/DiskConfig.swift"
test -f "Source/Shared/Library/ExpirationMode.swift" \\
&& ok "Source/Shared/Library/ExpirationMode.swift" \\
|| miss "missing critical file: Source/Shared/Library/ExpirationMode.swift"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 283 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~253d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/hyperoslo/Cache"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Cache is a lightweight Swift caching library that provides hybrid memory + disk storage with Codable support, expiry policies, and thread-safe operations. It uses a Chain-of-Responsibility pattern to compose storage backends (MemoryStorage, DiskStorage, HybridStorage) and eliminates boilerplate for persisting any Swift type that conforms to Codable. Modular Swift library organized as Source/Shared (core logic) and platform-specific code in Source/Mac. Core lives in Source/Shared/Library (Entry, DataSerializer, MemoryCapsule, ExpirationMode) and Source/Shared/Configuration (DiskConfig, MemoryConfig). Built with Swift Package Manager (Package.swift) and CocoaPods (Cache.podspec); Xcode project includes three schemes for iOS, macOS, and tvOS.
👥Who it's for
iOS, tvOS, and macOS developers who need to cache API responses, images, and JSON data without maintaining complex serialization logic or managing separate memory/disk sync—particularly those building apps that require offline support or response caching.
🌱Maturity & risk
Production-ready. The library is well-established with comprehensive unit tests, CI/CD via CircleCI, two build schemes (iOS and tvOS), detailed documentation in playgrounds, and appears actively maintained with a clear versioning strategy via CocoaPods. Swift 5 adoption and Codable reliance indicate modern standards.
Low risk for active projects. Single maintainer (hyperoslo organization) and the last commit data is not visible, so recency is unclear—worth checking CircleCI pipeline status. However, the focused scope (caching only) and test coverage reduce architectural risk. Dependency footprint is minimal given it's pure Swift with no external pod dependencies listed.
Active areas of work
No recent commit or active PR data is visible in the provided file structure, but the presence of multiple Playgrounds (SimpleStorage.playground, Storage.playground) suggests ongoing documentation efforts. The .circleci/config.yml indicates active CI monitoring.
🚀Get running
Clone and open in Xcode: git clone https://github.com/hyperoslo/Cache.git && cd Cache && open Cache.xcodeproj. Or use CocoaPods: add pod 'Cache' to your Podfile. Run tests via the iOS/macOS/tvOS schemes in Xcode.
Daily commands: Open Cache.xcodeproj in Xcode and select the Cache-iOS, Cache-macOS, or Cache-tvOS scheme, then build (Cmd+B) or run tests (Cmd+U). No dev server—this is a library. Playgrounds in the Playgrounds/ folder can be opened directly to explore API usage interactively.
🗺️Map of the codebase
Source/Shared/Storage/Storage.swift— Core Storage protocol defining the main cache interface that all implementations (Disk, Memory, Hybrid) conform to.Source/Shared/Storage/HybridStorage.swift— Primary composition layer combining memory and disk storage with configurable expiry and observation support.Source/Shared/Library/Transformer.swift— Critical serialization abstraction enabling type-safe storage and retrieval of arbitrary objects via TransformerFactory.Source/Shared/Configuration/DiskConfig.swift— Disk storage configuration controlling cache location, size limits, and expiration policies.Source/Shared/Library/ExpirationMode.swift— Defines expiration strategies (TTL, date-based) that govern cache invalidation across all storage types.Source/Shared/Storage/StorageObservationRegistry.swift— Manages storage change notifications allowing consumers to react to cache mutations via observation tokens.
🛠️How to make changes
Add support for a new Codable type
- Create conforming type with Codable protocol in your app code (
N/A (user code)) - TransformerFactory automatically detects Codable types via introspection (
Source/Shared/Library/TransformerFactory.swift) - Use Storage.set(_:forKey:expiry:) with the type; encoder/decoder handles rest (
Source/Shared/Storage/Storage.swift)
Create a custom transformer for unsupported types
- Implement Transformer<T> protocol with toData() and fromData() methods (
Source/Shared/Library/Transformer.swift) - Register in TransformerFactory.default or pass to storage constructor (
Source/Shared/Library/TransformerFactory.swift) - Call Storage.set(_:forKey:expiry:) with the custom type (
Source/Shared/Storage/Storage.swift)
Observe cache changes at storage level
- Call storage.observe() to get ObservationToken and closure callback (
Source/Shared/Storage/HybridStorage.swift) - StorageObservationRegistry broadcasts mutations (set, remove, removeAll) (
Source/Shared/Storage/StorageObservationRegistry.swift) - Hold token in property; observation auto-cancels on token dealloc (
Source/Shared/Library/ObservationToken.swift)
Configure hybrid cache with custom expiry policy
- Create MemoryConfig with count/cost limits and ExpirationMode (
Source/Shared/Configuration/MemoryConfig.swift) - Create DiskConfig with cache directory, byte limits, and expiry strategy (
Source/Shared/Configuration/DiskConfig.swift) - Pass configs to HybridStorage init; use .expiry(Expiry) for per-item TTL (
Source/Shared/Storage/HybridStorage.swift)
🔧Why these technologies
- Swift 5 generics + Codable — Type-safe, zero-overhead serialization for arbitrary Codable types without runtime casting
- NSCache + FileManager — NSCache auto-evicts by cost/count; FileManager provides persistence with full control over path and expiry
- MD5 hashing for disk keys — Normalizes arbitrary key strings to valid filesystem filenames (32 chars, no special chars)
- Observation tokens + closures — Memory-safe alternative to delegates; token deinit auto-cancels, avoiding retain cycles
⚖️Trade-offs already made
-
L1/L2 hybrid storage vs. single unified storage
- Why: Most apps need both speed (memory) and persistence (disk); hybrid avoids reserializing on every access
- Consequence: Slightly higher complexity (two backends) but 10–100× faster hit rate
-
File-based disk storage vs. SQLite/CoreData
- Why: Simpler, zero dependencies, works offline-first; suitable for blob caching (images, data)
- Consequence: No complex queries; expiry requires file-system scan; less efficient for highly structured data
-
Transformer protocol + factory vs. built-in serialization
- Why: Extensible: users can add custom serializers without modifying Cache code
- Consequence: Slight runtime overhead for type introspection; requires understanding of Codable/JSONEncoder
-
Synchronous APIs as default, AsyncStorage as wrapper
- Why: Backward compatibility, simple testing; DiskStorage I/O is fast enough for most use cases
- Consequence: Potential thread-blocking on disk reads; users must choose AsyncStorage for UI-
🪤Traps & gotchas
No obvious environment variables or external services required, but be aware: (1) DiskStorage paths are platform-specific (iOS uses Caches directory); check Source/Shared/Extensions/URL+Extensions.swift for details. (2) Codable conformance is mandatory—non-Codable objects will fail silently or throw at serialization time. (3) Thread-safety relies on DispatchQueues; be careful with custom Storage implementations to avoid race conditions. (4) Expiry cleanup is not automatic—expired objects remain on disk until explicitly evicted.
🏗️Architecture
💡Concepts to learn
- Chain-of-Responsibility Pattern — Cache's core design allows composing multiple storage layers (Memory → Disk) where each handler decides whether to process or delegate to the next; understanding this is essential to architect custom storage pipelines.
- Codable (Swift Serialization) — This library is built entirely around Codable; you must understand how to conform types to Codable and why manual JSONEncoder/Decoder setup is avoided.
- Thread-Safe Concurrent Access — Cache guarantees thread-safety via DispatchQueues and barriers; knowing how DispatchQueue.sync/async and concurrent queues work is critical for avoiding deadlocks or data races in custom implementations.
- Expiration & Time-To-Live (TTL) — The ExpirationMode enum implements TTL-based cache invalidation; understanding when and how expired entries are cleaned up is essential for predictable cache behavior in production.
- LRU & LFU Cache Eviction — MemoryConfig likely supports eviction policies; knowing the trade-offs between Least Recently Used and Least Frequently Used determines memory footprint and hit rates.
- Observer Pattern (Observation Tokens) — ObservationToken enables reactive updates when cache entries change; understanding subscriptions and cancellation tokens prevents memory leaks and enables efficient reactive UI binding.
- Hashing & MD5 (Consistent Key Generation) — Source/Shared/Library/MD5.swift generates stable cache keys; understanding deterministic hashing ensures cache keys are consistent across app launches and devices.
🔗Related repos
realm/realm-swift— Alternative persistence layer offering relational storage; some apps use Realm + Cache together for different data types.SDWebImage/SDWebImage— Specialized image caching library; Cache includes ImageWrapper but SDWebImage offers deeper image-specific optimizations.apple/swift-coredata— Apple's native persistence framework; Cache complements CoreData for simpler, lightweight caching without schema overhead.hyperoslo/Hype— Sibling hyperoslo library; likely integrates with Cache for full-stack API response + caching patterns.Alamofire/Alamofire— Popular HTTP networking library often paired with Cache to store API responses and handle offline scenarios.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for ExpirationMode and Expiry logic
The repo has ExpirationMode.swift and Expiry.swift in Source/Shared/Library but there's no visible test coverage in the file structure. These are critical cache features that determine when entries expire. Adding tests would ensure expiration behavior is reliable across iOS, macOS, and tvOS platforms.
- [ ] Create Tests/ExpirationTests.swift covering ExpirationMode enum cases
- [ ] Add tests for Expiry.swift initialization and expiration date calculations
- [ ] Test interaction between ExpirationMode and DiskStorage.swift expiration cleanup
- [ ] Test edge cases: negative timeIntervals, expired entries during retrieval, concurrent expiration checks
- [ ] Run tests across all schemes (Cache-iOS, Cache-macOS, Cache-tvOS)
Add integration tests for HybridStorage combining MemoryStorage and DiskStorage
HybridStorage.swift is a core feature that coordinates memory and disk caching, but there appear to be no dedicated tests for cross-layer interactions. Tests should verify fallback behavior, consistency, and performance characteristics when memory eviction occurs.
- [ ] Create Tests/HybridStorageIntegrationTests.swift
- [ ] Test read-through: item in disk but not memory gets loaded correctly
- [ ] Test write consistency: saving to hybrid updates both layers appropriately
- [ ] Test eviction cascade: when MemoryStorage evicts, verify DiskStorage retrieval still works
- [ ] Test concurrent access patterns using StorageObservationRegistry.swift
- [ ] Verify MemoryConfig and DiskConfig are properly respected in hybrid mode
Implement missing AsyncStorage tests for async/await API coverage
AsyncStorage.swift provides modern async/await bindings, but test coverage is likely missing. Given Swift's concurrency evolution and this repo's iOS/macOS support, comprehensive async tests ensure thread-safety and proper error handling (StorageError.swift variants).
- [ ] Create Tests/AsyncStorageTests.swift with async/await syntax
- [ ] Test async read/write operations don't block main thread
- [ ] Add tests for all StorageError cases: diskAccessFailure, decodingFailed, etc.
- [ ] Test cancellation behavior with async Task handling
- [ ] Test AsyncStorage + Transformer.swift combination with async transforms
- [ ] Verify KeyObservationRegistry.swift works correctly with async observations
🌿Good first issues
- Add unit tests for Source/Shared/Extensions/Hasher+constantAccrossExecutions.swift—no test coverage visible for hash consistency across app runs, which is critical for cache key determinism.
- Improve documentation in Source/Shared/Library/ImageWrapper.swift and Source/Shared/Library/JSONArrayWrapper.swift by adding inline usage examples and cross-references in the Playgrounds (currently sparse).
- Implement a
StatisticsorCacheMetricsclass to expose hit/miss rates and storage usage—currently no observability beyond ObservationToken, useful for debugging and app analytics.
⭐Top contributors
Click to expand
Top contributors
- @3lvis — 54 commits
- @kitwtnb — 8 commits
- @nerdsupremacist — 7 commits
- [@Ken Carroll](https://github.com/Ken Carroll) — 4 commits
- @agarmash — 4 commits
📝Recent commits
Click to expand
Recent commits
86165db— Merge pull request #346 from lazyvar/master (3lvis)12c81c3— Update Storage.swift (lazyvar)bde695c— Merge pull request #340 from gibachan/fix-unit-test (3lvis)bb7a3b7— Fix unit test (gibachan)81a0277— Merge pull request #333 from lucasromanomr/patch-1 (3lvis)c07b1b8— Update Cache.podspec (lucasromanomr)24e4710— Merge pull request #304 from boduoduo/fix/sortedIssue (3lvis)d2e8f5a— Merge pull request #329 from keniwhat/master (3lvis)ddce7b9— Delete commented line of code. (Ken Carroll)e2a8f2f— Remove unused code. (Ken Carroll)
🔒Security observations
The Cache library is a Swift caching framework with a reasonably secure codebase. No critical vulnerabilities were identified from static analysis of the file structure. The main concerns are related to the use of MD5 hashing (medium severity for non-cryptographic purposes), potential file path handling in DiskStorage, and general serialization security practices. The library demonstrates good security hygiene with inclusion of privacy manifest (PrivacyInfo.xcprivacy) and proper configuration management. No hardcoded credentials, insecure dependencies, or obvious injection vulnerabilities were detected. Recommend reviewing actual implementation details of file operations and serialization handlers to confirm security practices.
- Medium · MD5 Hashing Implementation —
Source/Shared/Library/MD5.swift. The codebase includes an MD5 hashing implementation (Source/Shared/Library/MD5.swift). MD5 is cryptographically broken and should not be used for security purposes. While MD5 may be acceptable for non-security use cases like cache keys, it indicates potential weak cryptographic practices. Fix: If MD5 is used for security purposes, migrate to SHA-256 or other modern hashing algorithms. If used only for non-security purposes (cache keys), document this clearly and consider using a faster, non-cryptographic hash function. - Low · Potential Unvalidated File Operations —
Source/Shared/Storage/DiskStorage.swift, Source/Shared/Extensions/FileManager+Extensions.swift. The codebase includes FileManager extensions (Source/Shared/Extensions/FileManager+Extensions.swift) and DiskStorage implementation. Without reviewing the actual implementation, there is a risk of path traversal vulnerabilities if user input is not properly validated when constructing file paths. Fix: Ensure all file path operations validate and sanitize input to prevent path traversal attacks. Use URL components rather than string concatenation, and avoid allowing users to specify arbitrary file paths. - Low · Serialization Security Considerations —
Source/Shared/Library/DataSerializer.swift, Source/Shared/Extensions/JSONDecoder+Extensions.swift. The library includes data serialization mechanisms (Source/Shared/Library/DataSerializer.swift) with JSON handling. Deserializing untrusted data can pose security risks if the implementation does not properly validate object types. Fix: Implement strict type validation during deserialization. Use codable protocol validation and avoid dynamic type instantiation from untrusted sources. Test with malformed and malicious JSON inputs.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.