spark-html-image 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/README.md +26 -0
  2. package/package.json +1 -1
  3. package/src/index.js +13 -2
package/README.md CHANGED
@@ -61,3 +61,29 @@ It runs in `closeBundle` (order `post`), after
61
61
  [`spark-prerender`](https://www.npmjs.com/package/spark-prerender) has written
62
62
  its per-route HTML — so prerendered pages are optimized too. Conversion uses
63
63
  [sharp](https://sharp.pixelplumbing.com/).
64
+
65
+ ## The Spark family
66
+
67
+ Small, single-purpose packages that share one philosophy: no compiler, no
68
+ virtual DOM, no build step required. Add only what you use.
69
+
70
+ | Package | What it does |
71
+ |---|---|
72
+ | [`spark-html`](https://www.npmjs.com/package/spark-html) | The runtime — components, reactivity, stores, forms, scoped styles. 13 kB gzip, 0 deps. |
73
+ | [`spark-html-router`](https://www.npmjs.com/package/spark-html-router) | `<template route>` routing — nested routes/layouts, `route.query`, active links. |
74
+ | [`spark-html-theme`](https://www.npmjs.com/package/spark-html-theme) | Dark/light/system theming in one line — persisted, no flash. |
75
+ | [`spark-html-head`](https://www.npmjs.com/package/spark-html-head) | Reactive `<title>`/`<meta>` per route + a `head` store. |
76
+ | [`spark-html-motion`](https://www.npmjs.com/package/spark-html-motion) | Enter/leave transitions on if/each blocks — `transition="fade|slide|scale"`. |
77
+ | [`spark-html-devtools`](https://www.npmjs.com/package/spark-html-devtools) | In-page devtools — live stores, component tree, patch activity. |
78
+ | [`spark-html-query`](https://www.npmjs.com/package/spark-html-query) | Declarative async data — a self-fetching store (`loading`/`error`/`data`/`refetch`). |
79
+ | [`spark-html-persist`](https://www.npmjs.com/package/spark-html-persist) | Persist stores to localStorage/sessionStorage in one line. |
80
+ | [`spark-html-websocket`](https://www.npmjs.com/package/spark-html-websocket) | A WebSocket as a reactive store — auto-reconnect, JSON, `send()`. |
81
+ | [`spark-prerender`](https://www.npmjs.com/package/spark-prerender) | Build-time SEO prerender + sitemap/robots — no SSR server. |
82
+ | [`spark-html-image`](https://www.npmjs.com/package/spark-html-image) | Build-time image optimization — webp/avif + responsive `srcset`, zero config. |
83
+ | [`spark-html-font`](https://www.npmjs.com/package/spark-html-font) | Font loading optimizer — preload + size-adjusted fallbacks, no FOUT. |
84
+ | [`spark-html-manifest`](https://www.npmjs.com/package/spark-html-manifest) | PWA manifest + icons + head tags (and optional service worker) from one config. |
85
+ | [`spark-html-offline`](https://www.npmjs.com/package/spark-html-offline) | Offline URL imports — a service worker that caches CDN components. |
86
+ | [`spark-html-sri`](https://www.npmjs.com/package/spark-html-sri) | Subresource Integrity — hash + verify assets and remote components. |
87
+ | [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a Vite + spark-html app in one command. |
88
+ | [`prettier-plugin-spark`](https://www.npmjs.com/package/prettier-plugin-spark) | Prettier for components — formats `<script>`/`<style>`, markup stays byte-for-byte. |
89
+ | [`spark-html-language-server`](https://www.npmjs.com/package/spark-html-language-server) | LSP — diagnostics, go-to-definition, prop autocomplete, hover docs. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spark-html-image",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Build-time image optimization for spark-html sites — a Vite plugin that converts <img> references to webp/avif with responsive srcset, zero config.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -121,7 +121,15 @@ export default function sparkImage(options = {}) {
121
121
  let m = meta.get(file);
122
122
  if (!m) {
123
123
  const info = await sharp(file).metadata();
124
- m = { width: info.width || 0, height: info.height || 0 };
124
+ // EXIF orientations 5–8 display the image rotated 90° the
125
+ // metadata reports the SENSOR dimensions, so swap to get the
126
+ // dimensions the page actually renders (and that the rotated
127
+ // variants below will have).
128
+ const swap = (info.orientation || 1) >= 5;
129
+ m = {
130
+ width: (swap ? info.height : info.width) || 0,
131
+ height: (swap ? info.width : info.height) || 0,
132
+ };
125
133
  meta.set(file, m);
126
134
  }
127
135
  // Widths strictly below the intrinsic width, plus the intrinsic
@@ -138,7 +146,10 @@ export default function sparkImage(options = {}) {
138
146
  const dest = destUrl.startsWith('/')
139
147
  ? join(root, destUrl.slice(1))
140
148
  : join(dirname(file), posix.basename(destUrl));
141
- let img = sharp(file);
149
+ // .rotate() with no args bakes the EXIF orientation into the
150
+ // pixels — webp/avif output drops the EXIF tag, so without
151
+ // this every phone photo would render sideways.
152
+ let img = sharp(file).rotate();
142
153
  if (w) img = img.resize({ width: w });
143
154
  await img[format]({ quality }).toFile(dest);
144
155
  converted.set(key, url);