125 lines
3.2 KiB
JavaScript
125 lines
3.2 KiB
JavaScript
// @ts-check
|
|
import crypto from "node:crypto";
|
|
import objectHash from "object-hash";
|
|
import getImageSources from "./getImageSources.js";
|
|
import getProcessedImage from "./getProcessedImage.js";
|
|
import getArtDirectedImages from "./getArtDirectedImages.js";
|
|
import pMap from "p-map";
|
|
import { get_cached_object, set_cached_object } from '@polymech/cache';
|
|
|
|
const imagesData = new Map();
|
|
|
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
export default async function ({
|
|
src,
|
|
type,
|
|
sizes: imagesizes,
|
|
format,
|
|
breakpoints,
|
|
placeholder,
|
|
fallbackFormat,
|
|
includeSourceFormat,
|
|
formatOptions,
|
|
artDirectives,
|
|
transformConfigs,
|
|
}) {
|
|
try {
|
|
const args = Array.from(arguments);
|
|
const hash = objectHash(args);
|
|
|
|
// Check in-memory cache first
|
|
if (imagesData.has(hash)) {
|
|
return imagesData.get(hash);
|
|
}
|
|
|
|
// Check persistent cache
|
|
const cacheKey = { src, type, imagesizes, format, breakpoints, placeholder, fallbackFormat, includeSourceFormat, formatOptions, artDirectives, transformConfigs };
|
|
const cachedResult = await get_cached_object(cacheKey, 'astro-imagetools');
|
|
|
|
if (cachedResult) {
|
|
console.log(`Cache hit for ${type} at ${src}`);
|
|
imagesData.set(hash, cachedResult);
|
|
return cachedResult;
|
|
}
|
|
|
|
const start = performance.now();
|
|
|
|
const { path, base, rest, image, imageWidth, imageHeight, imageFormat } =
|
|
await getProcessedImage(src, transformConfigs);
|
|
|
|
src = path;
|
|
|
|
rest.aspect = `${imageWidth / imageHeight}`;
|
|
if (!fallbackFormat) {
|
|
fallbackFormat = imageFormat;
|
|
}
|
|
|
|
// Fetch both image sources and art-directed images
|
|
const [mainImage, artDirectedImages] = await pMap(
|
|
[
|
|
async () =>
|
|
await getImageSources(
|
|
src,
|
|
base,
|
|
image,
|
|
format,
|
|
imageWidth,
|
|
imagesizes,
|
|
breakpoints,
|
|
placeholder,
|
|
imageFormat,
|
|
formatOptions,
|
|
fallbackFormat,
|
|
includeSourceFormat,
|
|
rest
|
|
),
|
|
async () => {
|
|
return await getArtDirectedImages(
|
|
artDirectives,
|
|
placeholder,
|
|
format,
|
|
imagesizes,
|
|
breakpoints,
|
|
fallbackFormat,
|
|
includeSourceFormat,
|
|
formatOptions,
|
|
rest
|
|
);
|
|
},
|
|
],
|
|
async (task) => await task(),
|
|
{ concurrency: 1 }
|
|
);
|
|
|
|
// Ensure artDirectedImages is an array
|
|
const images = Array.isArray(artDirectedImages) ? [...artDirectedImages, mainImage] : [mainImage];
|
|
|
|
const uuid = crypto.randomBytes(4).toString("hex").toUpperCase();
|
|
|
|
const returnObject = {
|
|
uuid,
|
|
images,
|
|
};
|
|
|
|
// Cache both in memory and persistently
|
|
imagesData.set(hash, returnObject);
|
|
await set_cached_object(cacheKey, 'astro-imagetools', returnObject, {
|
|
src: args[0].src,
|
|
type,
|
|
timestamp: Date.now()
|
|
});
|
|
|
|
const end = performance.now();
|
|
|
|
console.log(
|
|
`Responsive Image sets generated for ${type} at ${args[0].src} in ${end - start}ms`
|
|
);
|
|
|
|
return returnObject;
|
|
} catch (error) {
|
|
console.error("Error processing images:", error);
|
|
throw error;
|
|
}
|
|
}
|