@ammduncan/easel 0.2.15 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to easel. This project adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## 0.2.16 — 2026-05-23
6
+
7
+ ### Changed
8
+ - **PDF export quality bumped back up after the 0.2.15 size fix landed.** 0.2.15 traded crispness for size (JPEG 0.92 + DPR 2 → ~800 KB per card) — visible JPEG artefacts on type at zoom. Bumped to JPEG quality 1.0 + DPR 4 for the PDF target. Same compression trick (JPEG-in-PDF vs PNG-in-PDF) keeps the file at ~3–8 MB per card instead of the original 300+ MB; the higher quality settings just bring text back to "razor sharp at any zoom" without giving up the size win.
9
+ - PNG export unchanged (still lossless PNG @ DPR 4).
10
+
5
11
  ## 0.2.15 — 2026-05-23
6
12
 
7
13
  ### Fixed
@@ -867,18 +867,21 @@ ${body}
867
867
  document.body ? document.body.scrollHeight : 0,
868
868
  );
869
869
  // PNG target → lossless PNG @ pixelRatio 4 for crisp standalone files.
870
- // PDF target → JPEG @ quality 0.92 + pixelRatio 2. PDFs natively use
871
- // DCT compression for embedded images, so JPEG-in-PDF stays small;
872
- // PNG-in-PDF balloons (a tall card at DPR 4 produces 300+ MB PDFs).
870
+ // PDF target → JPEG @ quality 1.0 + pixelRatio 4. PDFs natively use
871
+ // DCT compression for embedded JPEGs, so even at max quality the PDF
872
+ // stays in the ~3-8 MB range for a typical card (vs ~300 MB if we
873
+ // embedded as PNG — see 0.2.15). 1.0 + DPR 4 keeps text razor-sharp
874
+ // at any zoom level; tuned down to 0.92 + DPR 2 in 0.2.15 dropped to
875
+ // ~800 KB but at the cost of visible JPEG artefacts on type.
873
876
  var rasterFn = format === "pdf" ? window.htmlToImage.toJpeg : window.htmlToImage.toPng;
874
877
  var rasterOpts = {
875
878
  backgroundColor: bgColor,
876
- pixelRatio: format === "pdf" ? 2 : 4,
879
+ pixelRatio: 4,
877
880
  cacheBust: true,
878
881
  width: width,
879
882
  height: height,
880
883
  };
881
- if (format === "pdf") rasterOpts.quality = 0.92;
884
+ if (format === "pdf") rasterOpts.quality = 1.0;
882
885
  rasterFn(document.documentElement, rasterOpts).then(function(dataUrl){
883
886
  parent.postMessage({ type: "easel:image-ready", pushId: pushId, dataUrl: dataUrl, filename: filename, format: format }, "*");
884
887
  }).catch(function(err){
@@ -903,7 +906,7 @@ ${body}
903
906
  const configScript =
904
907
  "<script src='https://cdn.jsdelivr.net/npm/html-to-image@1.11.13/dist/html-to-image.js'></script><script>(function(){function a(c){if(!c)return;if(c.theme==='light'||c.theme==='dark'){document.documentElement.setAttribute('data-theme',c.theme);window.__claudeDisplayTheme=c.theme}if(c.preset==='paper'||c.preset==='aurora'||c.preset==='slate'){document.documentElement.setAttribute('data-preset',c.preset);window.__claudeDisplayPreset=c.preset}if(c.density==='carded'||c.density==='flat'){document.documentElement.setAttribute('data-density',c.density);window.__claudeDisplayDensity=c.density}}a(" +
905
908
  JSON.stringify({ theme, preset, density }) +
906
- ");window.addEventListener('message',function(e){if(!e||!e.data)return;if(e.data.type==='easel:config')a(e.data);if(e.data.type==='easel:theme')a({theme:e.data.theme});if(e.data.type==='easel:print'){try{window.print()}catch(_){}}if(e.data.type==='easel:image'){var pid=e.data.pushId;var fn=e.data.filename||'push.png';var fmt=e.data.format==='pdf'?'pdf':'png';var bg=e.data.bgColor||'#ffffff';if(!window.htmlToImage)return;var rfn=fmt==='pdf'?window.htmlToImage.toJpeg:window.htmlToImage.toPng;var ropts={backgroundColor:bg,pixelRatio:fmt==='pdf'?2:4,cacheBust:true};if(fmt==='pdf')ropts.quality=0.92;rfn(document.body,ropts).then(function(u){parent.postMessage({type:'easel:image-ready',pushId:pid,dataUrl:u,filename:fn,format:fmt},'*')}).catch(function(err){console.error(err);parent.postMessage({type:'easel:image-error',pushId:pid,format:fmt,message:(err&&err.message)?err.message:String(err)},'*')})}})})();</script>";
909
+ ");window.addEventListener('message',function(e){if(!e||!e.data)return;if(e.data.type==='easel:config')a(e.data);if(e.data.type==='easel:theme')a({theme:e.data.theme});if(e.data.type==='easel:print'){try{window.print()}catch(_){}}if(e.data.type==='easel:image'){var pid=e.data.pushId;var fn=e.data.filename||'push.png';var fmt=e.data.format==='pdf'?'pdf':'png';var bg=e.data.bgColor||'#ffffff';if(!window.htmlToImage)return;var rfn=fmt==='pdf'?window.htmlToImage.toJpeg:window.htmlToImage.toPng;var ropts={backgroundColor:bg,pixelRatio:4,cacheBust:true};if(fmt==='pdf')ropts.quality=1.0;rfn(document.body,ropts).then(function(u){parent.postMessage({type:'easel:image-ready',pushId:pid,dataUrl:u,filename:fn,format:fmt},'*')}).catch(function(err){console.error(err);parent.postMessage({type:'easel:image-error',pushId:pid,format:fmt,message:(err&&err.message)?err.message:String(err)},'*')})}})})();</script>";
907
910
  const measureScript = "<script>" + selfMeasureScript(pushId) + "</script>";
908
911
  const combined = configScript + measureScript;
909
912
  if (/<\/body>/i.test(html)) return html.replace(/<\/body>/i, combined + "</body>");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ammduncan/easel",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "description": "A live browser tab for every Claude Code (and MCP) session. The push MCP tool appends HTML cards to a scrolling feed you keep open in split-screen.",
5
5
  "type": "module",
6
6
  "license": "MIT",