Design Goals
- Security - Only pre-configured packages can be queried
- Cache Efficiency - Maximize cache hits, minimize API calls
- Type Safety - Full runtime validation of all data
- Resilience - Handle provider failures gracefully
- Performance - Request coalescing prevents duplicate calls
Architecture Overview
Package Identification
Why Hash-Based IDs?
Traditional REST APIs use resource IDs like/api/packages/vuejs/vue. This has problems:
- Security - Anyone can query arbitrary packages
- Cache Invalidation - Changing config does not change the URL
- Ambiguity - Same package with different settings = same ID
What is in the Hash?
The hash includes everything that affects the package data:vuejs/vuewithmaxReleases: 10→ Hash Avuejs/vuewithmaxReleases: 20→ Hash B (different!)- Changing any provider setting → New hash → Cache miss
Hash Generation
Implementation inlibs/config/views/package.ts:28:
PackageConfigView
The view class encapsulates all package configuration:The Package Map
UserConfigView creates a fast lookup map:Package Service Flow
Cache Architecture
Multi-Layer Caching
Cache Key Structure
- Provider schema changes → New namespace → Cache miss
- Implementation changes → New namespace → Cache miss
- Prevents stale data when code changes
TTL Strategy
undefined (not found) is critical - prevents repeated failed API calls for:
- Typos in package names
- Deleted packages
- Non-existent versions
Request Coalescing
When multiple requests hit the same cache miss:server/libs/cache/coalescing-cache.ts:48:
- Multiple users open the same package simultaneously
- Cache expires and multiple requests arrive
- Server restarts and cache is cold
Provider Adapter Interface
Each provider implements a standard interface. Fromserver/libs/provider/index.ts:15:
Data Flow Through Provider
Package structure:
Security Model
Hash Validation
The API never accepts arbitrary package identifiers:Why This Matters
Without hash validation, users could:- Query any package on GitHub/NPM (security risk)
- Exhaust API rate limits by requesting random packages
- Probe for private package names
- Only packages in
lists.yamlcan be queried - Attacker cannot guess valid hashes (cryptographically secure)
- API rate limits are predictable and controlled
Error Handling
Error Types
Defined inserver/libs/provider/errors.ts:
Error Recovery
Performance Considerations
Cache Hit Ratio
Target: >95% cache hit ratio Factors affecting hit rate:- TTL configuration
- Number of unique packages
- User browsing patterns
Memory Usage
L1 cache stores deserialized objects:Cold Start
On server restart:- L1 cache is empty
- L2 cache survives (file-based)
- First requests populate L1 from L2
- External APIs only hit on L2 miss
Monitoring
Metrics to Track
- Cache Hit Rate - Should be >95%
- API Call Rate - Watch for spikes
- Package Fetch Latency - P95 < 100ms (cached)
- Provider Error Rate - Alert on >1%
Cache Statistics
The coalescing cache tracks:Summary
The package system provides:- Security via content-addressing - Only configured packages accessible
- Automatic cache invalidation - Config changes change hashes
- Multi-layer caching - L1 (memory) + L2 (file)
- Request coalescing - Prevents duplicate API calls
- Graceful degradation - Stale cache on provider errors