feat: implement LRU cache with invocation ID scoping for minimal mode response cache (#88509)
## Summary
Implements an LRU cache with compound keys for the minimal mode response
cache to improve cache hit rates during parallel revalidation scenarios.
**Problem**: The previous single-entry cache (`previousCacheItem`) keyed
by pathname caused cache collisions when multiple concurrent invocations
(e.g., during ISR revalidation) accessed the same pathname. Each
invocation would overwrite the previous entry, leading to cache misses
and redundant work.
**Solution**: An LRU cache using compound keys (`pathname +
invocationID`) that allows multiple invocations to cache entries for the
same pathname independently:
```
Cache Key Structure
─────────────────────
/blog/post-1\0inv-abc → {entry, expiresAt}
/blog/post-1\0inv-def → {entry, expiresAt}
/blog/post-1\0__ttl__ → {entry, expiresAt} (TTL fallback)
/api/data\0inv-ghi → {entry, expiresAt}
```
### Cache Key Strategy
- **With `x-invocation-id` header**: Entries are keyed by invocation ID
for exact-match lookups (always a cache hit if the entry exists)
- **Without header (TTL fallback)**: Entries use a `__ttl__` sentinel
key and validate via expiration timestamp
### Configuration via Environment Variables
Cache sizing can be tuned via environment variables (using
`NEXT_PRIVATE_*` prefix for infrastructure-level settings):
| Environment Variable | Default | Description |
|---------------------|---------|-------------|
| `NEXT_PRIVATE_RESPONSE_CACHE_MAX_SIZE` | 150 | Max entries in the LRU
cache |
| `NEXT_PRIVATE_RESPONSE_CACHE_TTL` | 10000 | TTL in ms for cache
entries (fallback validation) |
### LRU Cache Enhancement
Added an optional `onEvict` callback to `LRUCache` that fires when
entries are evicted due to capacity limits. This enables tracking
evicted invocation IDs for warning detection without introducing
timer-based cleanup.
### Eviction Warnings
When a cache entry is evicted and later accessed by the same invocation,
a warning is logged suggesting to increase
`NEXT_PRIVATE_RESPONSE_CACHE_MAX_SIZE`. This helps developers tune cache
sizes for their workload.
### Additional Changes
- Renamed header from `x-vercel-id` to `x-invocation-id` for clarity
- Added `withInvocationId()` test helper for cache testing
## Test Plan
- Existing response cache tests pass with updated header name
- Unit tests for `LRUCache` including `onEvict` callback behavior
- Updated standalone mode tests to use `withInvocationId()` helper