ReviewOS

also looking at this

stacks/rpx

feat: imgx integration — on-the-fly image transforms from query params

#2264
Merged glennmichael123 wants to merge feat/imgx-integration into main
15 files +1118 -16
10 days ago

Implements the integration Chris asked for: enable imgx: true (or rpx start --imgx) and the reverse proxy automatically implements imgix/meema-style image params on any image response — ?w=200&h=1200&q=80, fm/format (+auto content negotiation), fit/crop/ar/dpr, blur/sharp/greyscale/bri/sat/hue/tint, rot/flip/flop/bg. Param names and semantics follow the meema-api serverless (imgix-compatible) handler.

How it works

  • Powered by ts-images (imgx) — pure-TS decode → resize/ops → encode, all in-memory, lazily imported on first use (zero startup cost; a missing package degrades to passthrough with one warning).
  • Hooked post-upstream in createProxyFetchHandler (pool path, fetch fallback, and static file routes), modeled on the cleanUrls config → ProxyRoute threading, including daemon registry entries and a per-proxy override in multi-proxy configs.
  • Never breaks serving: non-image/non-200/param-less responses untouched; responses over maxInputBytes pass through still streaming; decode/encode failures serve the original bytes.
  • Bounded LRU cache keyed by path + normalized params + hash of upstream bytes — an unchanged upstream never re-encodes twice, a changed one misses naturally (no TTLs). x-rpx-imgx: hit|miss header for observability.
  • Transformed responses drop upstream ETag/Last-Modified, keep Cache-Control, and set Vary: accept for auto=format (negotiates WebP; AVIF is deliberately not auto-picked since real AV1 output needs a system avifenc).

Also in this PR

  • Docs page (docs/features/imgx.md + sidebar/README entries), --imgx CLI flag, public exports for parseImgxParams/applyImgxTransform/resolveImgx.
  • 23 new tests (param parsing, LRU, live-origin proxying, static routes, fallbacks, caching, content negotiation). Full suite: 455 pass / 0 fail.

Dependency note

Requires ts-images@^0.1.11: 0.1.10's published dist was unparseable — its own sideEffects: false made Bun's bundler tree-shake the whole library away (the exact failure ts-collect hit in 0.4.1/0.4.2). Fixed upstream in stacksjs/ts-images@a2d8908 (flag dropped + a prepublish dist smoke test) and released as v0.1.11.

🤖 Generated with Claude Code

15 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.