spark-html-image 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -1,18 +1,17 @@
1
1
  # ⚡ spark-html-image
2
2
 
3
3
  Build-time image optimization for [spark-html](https://www.npmjs.com/package/spark-html)
4
- sites — a Vite plugin that converts your `<img>` references to **webp/avif**
5
- with a responsive `srcset`, **zero config**. No more hand-written
6
- `scripts/optimize-images.js` wired into the build command.
4
+ sites — a `spark-html-bun` pipeline step that converts your `<img>` references
5
+ to **webp/avif** with a responsive `srcset`, **zero config**. No more
6
+ hand-written `scripts/optimize-images.js` wired into the build command.
7
7
 
8
8
  ```js
9
- // vite.config.js
10
- import spark from 'spark-html/vite';
11
- import prerender from 'spark-prerender/vite';
12
- import image from 'spark-html-image';
9
+ // spark.config.js
10
+ import prerender from 'spark-prerender/bun';
11
+ import image from 'spark-html-image/bun';
13
12
 
14
13
  export default {
15
- plugins: [spark(), prerender(), image()],
14
+ pipeline: [prerender(), image()],
16
15
  };
17
16
  ```
18
17
 
@@ -84,6 +83,6 @@ virtual DOM, no build step required. Add only what you use.
84
83
  | [`spark-html-manifest`](https://www.npmjs.com/package/spark-html-manifest) | PWA manifest + icons + head tags (and optional service worker) from one config. |
85
84
  | [`spark-html-offline`](https://www.npmjs.com/package/spark-html-offline) | Offline URL imports — a service worker that caches CDN components. |
86
85
  | [`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. |
86
+ | [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a spark-html app in one command. |
88
87
  | [`prettier-plugin-spark`](https://www.npmjs.com/package/prettier-plugin-spark) | Prettier for components — formats `<script>`/`<style>`, markup stays byte-for-byte. |
89
88
  | [`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,7 +1,7 @@
1
1
  {
2
2
  "name": "spark-html-image",
3
- "version": "0.1.1",
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.",
3
+ "version": "0.1.3",
4
+ "description": "Build-time image optimization for spark-html sites — a spark-html-bun build step that converts <img> references to webp/avif with responsive srcset, zero config.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "types": "./src/index.d.ts",
@@ -11,8 +11,7 @@
11
11
  "types": "./src/index.d.ts",
12
12
  "default": "./src/index.js"
13
13
  },
14
- "./vite": {
15
- "types": "./src/index.d.ts",
14
+ "./bun": {
16
15
  "default": "./src/index.js"
17
16
  }
18
17
  },
@@ -33,7 +32,7 @@
33
32
  },
34
33
  "keywords": [
35
34
  "spark-html",
36
- "vite-plugin",
35
+ "bun",
37
36
  "images",
38
37
  "webp",
39
38
  "avif",
package/src/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * spark-html-image — build-time image optimization (Vite plugin).
2
+ * spark-html-image — build-time image optimization (spark-html-bun step).
3
3
  * Converts local raster <img> references in the built HTML (pages and
4
4
  * component fragments) to webp/avif variants with a responsive srcset.
5
5
  */
@@ -19,10 +19,8 @@ export interface SparkImageOptions {
19
19
  lazy?: boolean;
20
20
  }
21
21
 
22
- /** Vite plugin: optimize <img> references in the build output. */
22
+ /** spark-html-bun pipeline step: optimize <img> references in the build output. */
23
23
  export default function sparkImage(options?: SparkImageOptions): {
24
24
  name: string;
25
- apply: 'build';
26
- configResolved(config: unknown): void;
27
- closeBundle: { order: 'post'; handler(): Promise<void> };
25
+ run(ctx: { outDir: string }): Promise<void>;
28
26
  };
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * spark-html-image — build-time image optimization for spark-html sites.
3
3
  *
4
- * A Vite plugin: after the build (and after spark-prerender has written its
4
+ * A build step: after the build (and after spark-prerender has written its
5
5
  * per-route HTML), it scans every *.html in the out dir — pages AND
6
6
  * components — for local raster <img> references, converts each to
7
7
  * webp/avif at several widths with sharp, and rewrites the tag:
@@ -15,15 +15,16 @@
15
15
  * The original file stays in place as the src fallback, so nothing breaks in
16
16
  * a browser (or crawler) that ignores srcset. Zero config:
17
17
  *
18
- * // vite.config.js
18
+ * // spark.config.js
19
19
  * import image from 'spark-html-image';
20
- * export default { plugins: [spark(), prerender(), image()] };
20
+ * export default { pipeline: [prerender(), image()] };
21
21
  *
22
22
  * With `picture: true` it instead wraps the img in <picture> with one
23
23
  * <source> per format (useful when you enable avif).
24
24
  *
25
25
  * No core involvement — this is the same pattern as spark-prerender:
26
- * build-time only, optional, nothing added to the runtime.
26
+ * build-time only, optional, nothing added to the runtime. It's a
27
+ * spark-html-bun pipeline step: { name, run({ outDir }) }.
27
28
  */
28
29
  import { join, dirname, extname, posix } from 'node:path';
29
30
  import { readFile, writeFile, readdir, stat } from 'node:fs/promises';
@@ -84,19 +85,10 @@ export default function sparkImage(options = {}) {
84
85
  const picture = options.picture === true;
85
86
  const lazy = options.lazy !== false;
86
87
 
87
- let outDir = 'dist';
88
-
89
88
  return {
90
89
  name: 'spark-html-image',
91
- apply: 'build',
92
- configResolved(config) {
93
- if (config && config.build && config.build.outDir) outDir = config.build.outDir;
94
- },
95
- // order:'post' → runs after spark-prerender's closeBundle has written the
96
- // per-route HTML, so prerendered pages are rewritten too.
97
- closeBundle: {
98
- order: 'post',
99
- async handler() {
90
+ // Put it after prerender() in the pipeline so per-route HTML is rewritten too.
91
+ async run({ outDir }) {
100
92
  // sharp is imported lazily so merely having the plugin installed
101
93
  // never loads the native module until a build actually runs.
102
94
  let sharp;
@@ -121,7 +113,15 @@ export default function sparkImage(options = {}) {
121
113
  let m = meta.get(file);
122
114
  if (!m) {
123
115
  const info = await sharp(file).metadata();
124
- m = { width: info.width || 0, height: info.height || 0 };
116
+ // EXIF orientations 5–8 display the image rotated 90° the
117
+ // metadata reports the SENSOR dimensions, so swap to get the
118
+ // dimensions the page actually renders (and that the rotated
119
+ // variants below will have).
120
+ const swap = (info.orientation || 1) >= 5;
121
+ m = {
122
+ width: (swap ? info.height : info.width) || 0,
123
+ height: (swap ? info.width : info.height) || 0,
124
+ };
125
125
  meta.set(file, m);
126
126
  }
127
127
  // Widths strictly below the intrinsic width, plus the intrinsic
@@ -138,7 +138,10 @@ export default function sparkImage(options = {}) {
138
138
  const dest = destUrl.startsWith('/')
139
139
  ? join(root, destUrl.slice(1))
140
140
  : join(dirname(file), posix.basename(destUrl));
141
- let img = sharp(file);
141
+ // .rotate() with no args bakes the EXIF orientation into the
142
+ // pixels — webp/avif output drops the EXIF tag, so without
143
+ // this every phone photo would render sideways.
144
+ let img = sharp(file).rotate();
142
145
  if (w) img = img.resize({ width: w });
143
146
  await img[format]({ quality }).toFile(dest);
144
147
  converted.set(key, url);
@@ -201,7 +204,6 @@ export default function sparkImage(options = {}) {
201
204
  if (images) {
202
205
  console.log(`[spark-html-image] optimized ${images} image reference(s) across ${files} file(s) (${formats.join('+')})`);
203
206
  }
204
- },
205
207
  },
206
208
  };
207
209
  }