@ecopages/image-processor 0.2.0-beta.4 → 0.2.0-beta.41

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.
@@ -1,103 +1,114 @@
1
- import { DEFAULT_LAYOUT } from "./constants.js";
2
- class ImageUtils {
3
- static BREAKPOINTS = {
4
- desktop: 1024,
5
- tablet: 768
6
- };
7
- static VIEWPORT_SIZES = {
8
- desktop: "70vw",
9
- tablet: "80vw",
10
- mobile: "100vw"
11
- };
12
- static DEFAULT_LAYOUT = DEFAULT_LAYOUT;
13
- /**
14
- * Generates a srcset string from processed image variants using relative paths
15
- * @param {ImageVariant[]} variants - Array of processed image variants
16
- * @returns {string} srcset attribute string
17
- * @private
18
- */
19
- static generateSrcset(variants) {
20
- return variants.sort((a, b) => b.width - a.width).map(({ src, width }) => `${src} ${width}w`).join(", ");
21
- }
22
- /**
23
- * Generates sizes attribute based on image variants.
24
- * Sizes are generated based on the variant widths and breakpoints.
25
- * Here we use a smart approach to generate sizes based on the variant widths.
26
- * We start with the largest variant and set a min-width condition for its width.
27
- * Then we add conditions for each variant based on the viewport width.
28
- * Finally, we add a catch-all for the smallest screens.
29
- * This approach ensures that the browser will select the correct image variant based on the viewport width.
30
- * @see https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#resolution_switching_different_sizes
31
- * @param {ImageVariant[]} variants - Array of processed image variants
32
- * @returns {string} sizes attribute string
33
- * @private
34
- */
35
- static generateSizes(variants) {
36
- if (!variants?.length) return "";
37
- const sortedVariants = [...variants].sort((a, b) => b.width - a.width);
38
- const [largest, ...rest] = sortedVariants;
39
- const conditions = [
40
- `(min-width: ${largest.width}px) ${largest.width}px`,
41
- ...rest.map((variant) => {
42
- if (variant.width >= ImageUtils.BREAKPOINTS.desktop) {
43
- return `(min-width: ${variant.width}px) ${ImageUtils.VIEWPORT_SIZES.desktop}`;
44
- }
45
- if (variant.width >= ImageUtils.BREAKPOINTS.tablet) {
46
- return `(min-width: ${variant.width}px) ${ImageUtils.VIEWPORT_SIZES.tablet}`;
47
- }
48
- return null;
49
- }).filter(Boolean),
50
- ImageUtils.VIEWPORT_SIZES.mobile
51
- ];
52
- return conditions.join(", ");
53
- }
54
- /**
55
- * Generates a styles string based on image layout and config
56
- * @param {ImageLayout} layout - Image layout type
57
- * @param {LayoutAttributes} config - Image layout configuration
58
- * @returns {string} styles string
59
- * @private
60
- */
61
- static generateLayoutStyles(config) {
62
- const layout = config.layout || ImageUtils.DEFAULT_LAYOUT;
63
- const styles = [["object-fit", "cover"]];
64
- if (config.aspectRatio) {
65
- styles.push(["aspect-ratio", config.aspectRatio]);
1
+ import { DEFAULT_LAYOUT } from './constants.js';
2
+ /**
3
+ * ImageUtils
4
+ * This class contains utility methods for working with images
5
+ * It contains methods for generating srcset, sizes and styles attributes for the image element
6
+ */
7
+ export class ImageUtils {
8
+ static BREAKPOINTS = {
9
+ desktop: 1024,
10
+ tablet: 768,
11
+ };
12
+ static VIEWPORT_SIZES = {
13
+ desktop: '70vw',
14
+ tablet: '80vw',
15
+ mobile: '100vw',
16
+ };
17
+ static DEFAULT_LAYOUT = DEFAULT_LAYOUT;
18
+ /**
19
+ * Generates a srcset string from processed image variants using relative paths
20
+ * @param {ImageVariant[]} variants - Array of processed image variants
21
+ * @returns {string} srcset attribute string
22
+ * @private
23
+ */
24
+ static generateSrcset(variants) {
25
+ return variants
26
+ .sort((a, b) => b.width - a.width)
27
+ .map(({ src, width }) => `${src} ${width}w`)
28
+ .join(', ');
66
29
  }
67
- switch (layout) {
68
- case "fixed":
69
- if (config.width) {
70
- styles.push(["width", `${config.width}px`], ["min-width", `${config.width}px`]);
71
- }
72
- if (config.height) {
73
- styles.push(["height", `${config.height}px`], ["min-height", `${config.height}px`]);
74
- }
75
- break;
76
- case "constrained":
77
- styles.push(["width", "100%"]);
78
- if (config.width && config.height) {
79
- styles.push(["max-width", `${config.width}px`], ["max-height", `${config.height}px`]);
80
- if (!config.aspectRatio) {
81
- styles.push(["aspect-ratio", `${config.width}/${config.height}`]);
82
- }
83
- } else if (config.height) {
84
- styles.push(["height", `${config.height}px`], ["min-height", `${config.height}px`]);
85
- } else if (config.width) {
86
- styles.push(["max-width", `${config.width}px`]);
87
- } else if (!config.aspectRatio) {
88
- styles.push(["aspect-ratio", `${config.attributes.width}/${config.attributes.height}`]);
30
+ /**
31
+ * Generates sizes attribute based on image variants.
32
+ * Sizes are generated based on the variant widths and breakpoints.
33
+ * Here we use a smart approach to generate sizes based on the variant widths.
34
+ * We start with the largest variant and set a min-width condition for its width.
35
+ * Then we add conditions for each variant based on the viewport width.
36
+ * Finally, we add a catch-all for the smallest screens.
37
+ * This approach ensures that the browser will select the correct image variant based on the viewport width.
38
+ * @see https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#resolution_switching_different_sizes
39
+ * @param {ImageVariant[]} variants - Array of processed image variants
40
+ * @returns {string} sizes attribute string
41
+ * @private
42
+ */
43
+ static generateSizes(variants) {
44
+ if (!variants?.length)
45
+ return '';
46
+ const sortedVariants = [...variants].sort((a, b) => b.width - a.width);
47
+ const [largest, ...rest] = sortedVariants;
48
+ const conditions = [
49
+ `(min-width: ${largest.width}px) ${largest.width}px`,
50
+ ...rest
51
+ .map((variant) => {
52
+ if (variant.width >= ImageUtils.BREAKPOINTS.desktop) {
53
+ return `(min-width: ${variant.width}px) ${ImageUtils.VIEWPORT_SIZES.desktop}`;
54
+ }
55
+ if (variant.width >= ImageUtils.BREAKPOINTS.tablet) {
56
+ return `(min-width: ${variant.width}px) ${ImageUtils.VIEWPORT_SIZES.tablet}`;
57
+ }
58
+ return null;
59
+ })
60
+ .filter(Boolean),
61
+ ImageUtils.VIEWPORT_SIZES.mobile,
62
+ ];
63
+ return conditions.join(', ');
64
+ }
65
+ /**
66
+ * Generates a styles string based on image layout and config
67
+ * @param {ImageLayout} layout - Image layout type
68
+ * @param {LayoutAttributes} config - Image layout configuration
69
+ * @returns {string} styles string
70
+ * @private
71
+ */
72
+ static generateLayoutStyles(config) {
73
+ const layout = config.layout || ImageUtils.DEFAULT_LAYOUT;
74
+ const styles = [['object-fit', 'cover']];
75
+ if (config.aspectRatio) {
76
+ styles.push(['aspect-ratio', config.aspectRatio]);
89
77
  }
90
- break;
91
- case "full-width":
92
- styles.push(["width", "100%"]);
93
- if (config.height) {
94
- styles.push(["height", `${config.height}px`], ["min-height", `${config.height}px`]);
78
+ switch (layout) {
79
+ case 'fixed':
80
+ if (config.width) {
81
+ styles.push(['width', `${config.width}px`], ['min-width', `${config.width}px`]);
82
+ }
83
+ if (config.height) {
84
+ styles.push(['height', `${config.height}px`], ['min-height', `${config.height}px`]);
85
+ }
86
+ break;
87
+ case 'constrained':
88
+ styles.push(['width', '100%']);
89
+ if (config.width && config.height) {
90
+ styles.push(['max-width', `${config.width}px`], ['max-height', `${config.height}px`]);
91
+ if (!config.aspectRatio) {
92
+ styles.push(['aspect-ratio', `${config.width}/${config.height}`]);
93
+ }
94
+ }
95
+ else if (config.height) {
96
+ styles.push(['height', `${config.height}px`], ['min-height', `${config.height}px`]);
97
+ }
98
+ else if (config.width) {
99
+ styles.push(['max-width', `${config.width}px`]);
100
+ }
101
+ else if (!config.aspectRatio) {
102
+ styles.push(['aspect-ratio', `${config.attributes.width}/${config.attributes.height}`]);
103
+ }
104
+ break;
105
+ case 'full-width':
106
+ styles.push(['width', '100%']);
107
+ if (config.height) {
108
+ styles.push(['height', `${config.height}px`], ['min-height', `${config.height}px`]);
109
+ }
110
+ break;
95
111
  }
96
- break;
112
+ return styles;
97
113
  }
98
- return styles;
99
- }
100
114
  }
101
- export {
102
- ImageUtils
103
- };
package/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from "./image-processor.js";
2
- export * from "./plugin.js";
3
- export * from "./types.js";
1
+ export * from './image-processor.js';
2
+ export * from './plugin.js';
3
+ export * from './types.js';
package/src/plugin.d.ts CHANGED
@@ -32,7 +32,7 @@ export interface ImageProcessorConfig {
32
32
  * ImageMap
33
33
  * This is the representation of the image map in the virtual module
34
34
  */
35
- export type ImageMap = Record<string, ImageSpecifications>;
35
+ export type { ImageMap } from './image-runtime-state.js';
36
36
  /**
37
37
  * ImageProcessorPlugin
38
38
  * A Processor for optimizing images.
@@ -54,22 +54,29 @@ export declare class ImageProcessorPlugin extends Processor<ImageProcessorConfig
54
54
  */
55
55
  private replaceProcessedImages;
56
56
  /**
57
- * Prepares the image virtual-module state before config build seals the app
58
- * manifest.
57
+ * Resolves processor config and creates the sharp-backed worker instance.
58
+ */
59
+ private initializeProcessor;
60
+ /**
61
+ * Prepares build-facing processor state before config build seals the app manifest.
62
+ *
63
+ * @remarks
64
+ * Image processing stays in {@link setup}; this hook only initializes config and
65
+ * restores any previously generated virtual-module state from disk.
59
66
  */
60
67
  prepareBuildContributions(): Promise<void>;
61
68
  private getRuntimeVirtualModulePath;
62
69
  private getGeneratedOutputPath;
63
- private hasGeneratedOutputs;
64
- private rehydrateGeneratedOutputs;
65
70
  /**
66
- * Generate dependencies for processor.
67
- * It is ossible to define which one should be included in the final bundle based on the environment.
68
- * @returns
71
+ * Restores in-memory image state from previously generated dist artifacts.
72
+ *
73
+ * @returns `true` when state was restored without invoking sharp.
69
74
  */
70
- private generateDependencies;
75
+ private syncProcessedImagesFromDisk;
76
+ private ensureGeneratedOutputs;
77
+ private writeGeneratedFile;
71
78
  /**
72
- * Prepares build contributions if not already done and rehydrates previously generated image outputs.
79
+ * Ensures optimized image outputs and virtual-module state exist on disk.
73
80
  */
74
81
  setup(): Promise<void>;
75
82
  /**