When renderUrlPdf() sets up request interception for SSRF DNS pinning,
the interceptor and event listener were never cleaned up in recyclePage().
This could cause subsequent HTML-to-PDF conversions on the same pooled
page to have external resources blocked by the stale interceptor.
- Export recyclePage for testability
- Add removeAllListeners('request') + setRequestInterception(false)
- Add browser-recycle.test.ts with TDD (red→green verified)
Tests: 443 passing (was 442)
- Add scale, pageRanges, preferCSSPageSize, width, height to PdfOptions
- Add headerTemplate, footerTemplate, displayHeaderFooter to docs
- Pass all options through routes to browser service for HTML, Markdown, and URL endpoints
- Export PdfRenderOptions interface for type reuse
- Bump version to 0.4.5
- Launch BROWSER_COUNT separate Chromium instances (default: 2)
- Each with PAGES_PER_BROWSER pages (default: 8, 16 total)
- Round-robin distribution across browser instances
- Independent restart scheduling per browser
- Updated health endpoint to show per-browser stats
- docker-compose: added BROWSER_COUNT and PAGES_PER_BROWSER env vars
BUG-007: Unwrap req.body.data for template endpoint (docs show wrapped format)
BUG-008: Default PDF margins set to 0 (user can override via request body)
BUG-006: Copy button shows Copied! for 2s then reverts