polymech-astro/packages/imagetools_3/api/utils/getImage.js
2025-12-24 11:47:18 +01:00

121 lines
2.9 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 { join, parse, relative } from "node:path";
import fs from "node:fs";
const imagesData = new Map();
// Cache helpers moved to plugin level
function getDefaultImage() {
const cwd = process.cwd();
const filepath = join(cwd, "public", "images", "default.png");
const src = join("/", relative(cwd, filepath));
return { src, base: "default" };
}
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);
}
const {
path,
base,
rest,
image,
imageWidth,
imageHeight,
imageFormat
} = await getProcessedImage(src, transformConfigs, { skipCache: false });
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];
// Create deterministic UUID based on input hash for consistent caching
const uuid = crypto.createHash('md5').update(hash).digest("hex").slice(0, 8).toUpperCase();
const returnObject = {
uuid,
images,
};
// Cache only in memory at this level
imagesData.set(hash, returnObject);
// Persistent caching moved to plugin level for proper store management
return returnObject;
} catch (error) {
console.error(`Error processing images:: ${src}`, error, error.stack);
throw error;
}
}