Skip to content

Conversation

@jakejarvis
Copy link
Owner

@jakejarvis jakejarvis commented Oct 14, 2025

Summary by CodeRabbit

  • Refactor

    • Switched generated images (screenshots, favicons, social/SEO covers) to WebP for smaller files and faster load times.
    • Updated watermarking and upload flows to handle WebP; filenames now use .webp.
  • Tests

    • Updated tests and mocks to reflect WebP outputs and new image handling.

@vercel
Copy link

vercel bot commented Oct 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
hoot Ready Ready Preview Comment Oct 14, 2025 4:47pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Walkthrough

Switched image processing from PNG-centric functions to WebP-oriented utilities. Renamed APIs and parameters (png → buffer), replaced optimizePngCover with optimizeImageCover, and updated tests and services (favicon, screenshot, SEO, storage) to use WebP outputs and new function names. Removed convertBufferToSquarePng from the public API.

Changes

Cohort / File(s) Summary
Image library API and behavior
lib/image.ts, lib/image.test.ts
Renamed convertBufferToPngCover → convertBufferToImageCover; replaced optimizePngCover → optimizeImageCover; updated addWatermarkToScreenshot to accept buffer; removed convertBufferToSquarePng; internal pipelines target WebP; tests updated to import/use new exports and expect WebP.
Storage interface and tests
lib/storage.ts, lib/storage.test.ts
uploadImage signature changed (png → buffer); filename generation now .webp; tests updated payload field and expected extension.
Favicon service and test
server/services/favicon.ts, server/services/favicon.test.ts
Switched to convertBufferToImageCover; variables/logs updated from png to webp; mock sharp pipeline now returns webp().
Screenshot service and test
server/services/screenshot.ts, server/services/screenshot.test.ts
Replaced optimizePngCover with optimizeImageCover; renamed internal variables; updated upload payload to buffer; adjusted logs; test mocks aligned.
SEO service
server/services/seo.ts
Updated import and usage to optimizeImageCover; renamed local vars; upload payload switched from png to buffer.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant ScreenshotSvc as Screenshot Service
  participant ImageLib as lib/image (optimizeImageCover, addWatermarkToScreenshot)
  participant Storage as lib/storage (uploadImage)
  
  User->>ScreenshotSvc: Request social image
  ScreenshotSvc->>ImageLib: addWatermarkToScreenshot(buffer, w, h)
  ImageLib-->>ScreenshotSvc: watermarked Buffer (WebP)
  ScreenshotSvc->>ImageLib: optimizeImageCover(buffer, w, h)
  ImageLib-->>ScreenshotSvc: optimized Buffer (WebP)
  ScreenshotSvc->>Storage: uploadImage({ buffer, width, height, ... })
  Storage-->>ScreenshotSvc: { url, key(.webp) }
  ScreenshotSvc-->>User: Response with image URL
Loading
sequenceDiagram
  autonumber
  actor Crawler
  participant FaviconSvc as Favicon Service
  participant ImageLib as lib/image
  participant Storage as lib/storage

  Crawler->>FaviconSvc: Provide source icon buffer
  FaviconSvc->>ImageLib: convertBufferToImageCover(buffer, size, hint)
  ImageLib-->>FaviconSvc: webp Buffer
  FaviconSvc->>Storage: uploadImage({ buffer, width, height, ... })
  Storage-->>FaviconSvc: { url, key(.webp) }
  FaviconSvc-->>Crawler: URL to WebP favicon
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I nibbled PNGs to WebP dreams,
Hop-hop through buffers, swift new streams.
I trimmed old squares, retired their song,
And stamped a watermark along.
New names, same warren—clean and neat,
.webp carrots taste so sweet! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately captures the primary objective of the changeset, which is refactoring image processing functions to produce WebP output instead of PNG, matching the modifications across code and tests.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/webp

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19f7cdf and f2975f5.

📒 Files selected for processing (9)
  • lib/image.test.ts (5 hunks)
  • lib/image.ts (4 hunks)
  • lib/storage.test.ts (7 hunks)
  • lib/storage.ts (2 hunks)
  • server/services/favicon.test.ts (1 hunks)
  • server/services/favicon.ts (3 hunks)
  • server/services/screenshot.test.ts (1 hunks)
  • server/services/screenshot.ts (3 hunks)
  • server/services/seo.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use TypeScript only with strict mode enabled
Prefer small, pure modules (approximately ≤300 LOC)
Use 2-space indentation across the codebase
Consolidate internal imports using @/... path aliases

**/*.{ts,tsx}: Import internal modules via @/... path aliases
Prefer small, pure modules (approximately ≤300 LOC)
Use 2-space indentation

Files:

  • server/services/favicon.ts
  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/seo.ts
  • lib/storage.test.ts
  • lib/image.ts
  • lib/storage.ts
  • server/services/favicon.test.ts
{app,components,hooks,lib,server}/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use kebab-case for files and folders

Files:

  • server/services/favicon.ts
  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/seo.ts
  • lib/storage.test.ts
  • lib/image.ts
  • lib/storage.ts
  • server/services/favicon.test.ts
{app/api,server}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Validate all external inputs with Zod for API routes and server code

Files:

  • server/services/favicon.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/seo.ts
  • server/services/favicon.test.ts
server/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use server-only imports for sensitive modules in server code

Place backend integrations and tRPC routers under server/; isolate DNS, RDAP/WHOIS, TLS, and header probing services there

Files:

  • server/services/favicon.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/seo.ts
  • server/services/favicon.test.ts
server/services/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Cache Cloudflare DoH, RDAP, TLS, and header probes via lib/cache and apply retry backoff to respect provider limits

Files:

  • server/services/favicon.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/seo.ts
  • server/services/favicon.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{ts,tsx}: When testing domain UI, mock Radix primitives (e.g., Accordion, Tooltip)
Mock URL.createObjectURL and URL.revokeObjectURL with vi.fn() in tests that need them

Files:

  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • lib/storage.test.ts
  • server/services/favicon.test.ts
server/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Server tests should use hoisted ESM mocks, unique cache domains, and reset Redis between tests

Files:

  • server/services/screenshot.test.ts
  • server/services/favicon.test.ts
server/services/screenshot.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create tests that mock Puppeteer and UploadThing for the screenshot service

Files:

  • server/services/screenshot.test.ts
server/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

server/**/*.{test,spec}.{ts,tsx}: In server tests, prefer vi.hoisted for ESM module mocks (e.g., node:tls)
In server tests, use unique cache keys/domains and call global.__redisTestHelper.reset() in afterEach

Files:

  • server/services/screenshot.test.ts
  • server/services/favicon.test.ts
server/services/screenshot.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Tests for the screenshot service should use hoisted mocks for puppeteer/puppeteer-core and @sparticuz/chromium

Files:

  • server/services/screenshot.test.ts
server/services/screenshot.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Implement screenshots in server/services/screenshot.ts using Puppeteer

For screenshots on Vercel, prefer puppeteer-core with @sparticuz/chromium; locally you may set PUPPETEER_EXECUTABLE_PATH or PUPPETEER_SKIP_DOWNLOAD=1; HOOT_USER_AGENT can override UA

Files:

  • server/services/screenshot.ts
lib/storage.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create tests covering upload helpers in lib/storage.ts

Files:

  • lib/storage.test.ts
lib/storage.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

lib/storage.ts should upload via UploadThing and return { url, key } stored in Redis with TTLs

Files:

  • lib/storage.ts
🧠 Learnings (6)
📚 Learning: 2025-10-06T19:08:35.300Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T19:08:35.300Z
Learning: Applies to server/services/screenshot.test.ts : Create tests that mock Puppeteer and UploadThing for the screenshot service

Applied to files:

  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/favicon.test.ts
📚 Learning: 2025-10-06T19:09:51.743Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: AGENTS.md:0-0
Timestamp: 2025-10-06T19:09:51.743Z
Learning: Applies to server/services/screenshot.{test,spec}.{ts,tsx} : Tests for the screenshot service should use hoisted mocks for puppeteer/puppeteer-core and sparticuz/chromium

Applied to files:

  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
  • server/services/favicon.test.ts
📚 Learning: 2025-10-06T19:08:35.300Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T19:08:35.300Z
Learning: Applies to server/services/screenshot.ts : Implement screenshots in `server/services/screenshot.ts` using Puppeteer

Applied to files:

  • lib/image.test.ts
  • server/services/screenshot.test.ts
  • server/services/screenshot.ts
📚 Learning: 2025-10-06T19:09:51.743Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: AGENTS.md:0-0
Timestamp: 2025-10-06T19:09:51.743Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Mock URL.createObjectURL and URL.revokeObjectURL with vi.fn() in tests that need them

Applied to files:

  • server/services/screenshot.test.ts
  • server/services/favicon.test.ts
📚 Learning: 2025-10-06T19:09:51.743Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: AGENTS.md:0-0
Timestamp: 2025-10-06T19:09:51.743Z
Learning: Applies to server/services/screenshot.ts : For screenshots on Vercel, prefer puppeteer-core with sparticuz/chromium; locally you may set PUPPETEER_EXECUTABLE_PATH or PUPPETEER_SKIP_DOWNLOAD=1; HOOT_USER_AGENT can override UA

Applied to files:

  • server/services/screenshot.ts
📚 Learning: 2025-10-06T19:08:35.300Z
Learnt from: CR
PR: jakejarvis/hoot#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T19:08:35.300Z
Learning: Applies to lib/storage.test.ts : Create tests covering upload helpers in `lib/storage.ts`

Applied to files:

  • lib/storage.test.ts
  • lib/storage.ts
🧬 Code graph analysis (4)
server/services/favicon.ts (1)
lib/image.ts (1)
  • convertBufferToImageCover (15-68)
lib/image.test.ts (1)
lib/image.ts (1)
  • optimizeImageCover (70-79)
server/services/screenshot.ts (2)
lib/image.ts (2)
  • optimizeImageCover (70-79)
  • addWatermarkToScreenshot (81-118)
lib/storage.ts (1)
  • uploadImage (169-181)
server/services/seo.ts (2)
lib/image.ts (1)
  • optimizeImageCover (70-79)
lib/storage.ts (1)
  • uploadImage (169-181)
🔇 Additional comments (22)
lib/image.ts (4)

15-22: LGTM: Function renamed and refactored correctly.

The function name and internal call have been properly updated to use the more generic convertBufferToImageCover and optimizeImageCover. The WebP output format is now applied consistently.


70-79: LGTM: WebP output format implemented correctly.

The function now outputs WebP format using Sharp's .webp({}) method. The function signature has been appropriately updated to use buffer instead of png.


81-118: LGTM: Watermark function updated correctly for WebP output.

The parameter has been renamed from png to buffer, and the output format has been changed to WebP. The watermarking logic remains intact.


27-68: Confirm direct WebP output support in icojs.parse

The code uses parse(..., 'image/png') then optimizeImageCover. Verify if icojs.parse supports 'image/webp' or raw buffer output to eliminate the PNG intermediate.

server/services/seo.ts (2)

3-3: LGTM: Import updated to new function name.

The import correctly references the renamed optimizeImageCover function.


255-264: LGTM: Variable naming and upload payload updated correctly.

The variable has been renamed from png to image to better reflect the generic image format, and the upload payload now uses the buffer parameter name, aligning with the updated API.

server/services/screenshot.test.ts (1)

38-38: LGTM: Mock updated to reflect renamed function.

The mock correctly exports optimizeImageCover instead of optimizePngCover, maintaining the same function signature.

server/services/favicon.test.ts (1)

14-23: LGTM: Mock updated to produce WebP output.

The Sharp mock has been correctly updated to use .webp() instead of .png(), and the comment has been updated to reflect this change. This aligns with the new image processing flow.

server/services/favicon.ts (3)

3-3: LGTM: Import updated to new function name.

The import correctly references the renamed convertBufferToImageCover function.


161-171: LGTM: Function call and variable naming updated correctly.

The conversion function has been updated to convertBufferToImageCover, and the variable has been renamed from png to webp to accurately reflect the output format. The log message has also been updated accordingly.


187-187: LGTM: Upload payload updated to use buffer parameter.

The upload call now correctly uses buffer: webp instead of the old png parameter name.

lib/storage.test.ts (2)

36-36: LGTM: Test fixtures updated to use buffer parameter.

All test cases have been correctly updated to use the buffer parameter instead of png, aligning with the updated API signature.

Also applies to: 53-53, 77-77, 101-101, 117-117, 140-140


161-161: LGTM: Filename expectation updated to WebP extension.

The test now correctly expects the filename to have a .webp extension instead of .png, reflecting the format change.

lib/image.test.ts (5)

4-4: LGTM: Imports updated to new function names.

The imports correctly reference optimizeImageCover and addWatermarkToScreenshot.


8-35: LGTM: Test updated to verify WebP output.

The test description and assertions have been updated to verify that the function produces valid WebP buffers instead of PNG. The metadata check correctly expects webp format.


37-70: LGTM: Font scaling test updated for WebP format.

The test correctly verifies that WebP buffers are produced at different sizes, with appropriate comments updated.


72-91: LGTM: Standard dimensions test updated for WebP format.

The test correctly verifies WebP output for standard screenshot dimensions.


93-113: LGTM: Test renamed and updated for WebP optimization.

The test has been correctly renamed from testing optimizePngCover to optimizeImageCover, and the assertions verify WebP format output.

server/services/screenshot.ts (3)

5-5: LGTM: Import updated to new function name.

The import correctly references the renamed optimizeImageCover function.


193-209: LGTM: Image optimization and watermarking flow updated correctly.

The code now uses optimizeImageCover and the variable has been renamed from pngWithWatermark to withWatermark to be more format-agnostic. The log message has been appropriately updated to remove PNG-specific references.


216-216: LGTM: Upload payload updated to use buffer parameter.

The upload call now correctly uses buffer: withWatermark instead of the old parameter name.

lib/storage.ts (1)

55-55: Verify UploadThing MIME type handling for WebP
UploadThing supports WebP (image/webp) but enforces MIME‐type validation. Confirm your upload route allows image or image/webp and that uploads include the correct Content-Type (x-ut-file-type).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Oct 14, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.25%. Comparing base (19f7cdf) to head (f2975f5).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
server/services/seo.ts 25.00% 3 Missing ⚠️
lib/image.ts 90.00% 1 Missing ⚠️
server/services/favicon.ts 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #93      +/-   ##
==========================================
- Coverage   69.37%   69.25%   -0.12%     
==========================================
  Files         116      116              
  Lines        9077     9062      -15     
  Branches      794      790       -4     
==========================================
- Hits         6297     6276      -21     
- Misses       2748     2755       +7     
+ Partials       32       31       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jakejarvis jakejarvis merged commit 4b64ef1 into main Oct 14, 2025
6 checks passed
@jakejarvis jakejarvis deleted the feat/webp branch October 14, 2025 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants