diff --git a/src/components/Image.astro b/src/components/Image.astro
index 5e47874..bf6c21f 100644
--- a/src/components/Image.astro
+++ b/src/components/Image.astro
@@ -2,7 +2,7 @@
import type { ImageMetadata } from "astro";
import { Picture as AstroImage } from "astro:assets";
import { inferRemoteSize } from "astro/assets/utils";
-import { generateThumbHash, getImageBuffer, getExifData } from "@helpers/image";
+import { getProcessedImage } from "@helpers/image";
interface Props {
src: ImageMetadata & { fsPath?: string; src?: string };
alt: string;
@@ -45,12 +45,11 @@ const {
thumbnail = false,
} = Astro.props;
-
-
const imageOk = await checkImage(image);
-const imageBuffer = imageOk && (await getImageBuffer(image));
-let thumbhash = imageBuffer && (await generateThumbHash(imageBuffer));
-let exif = imageBuffer && (await getExifData(imageBuffer));
+
+const { thumbhash, exif } = imageOk
+ ? await getProcessedImage(image)
+ : { thumbhash: undefined, exif: undefined };
const definedSizes = [
{
diff --git a/src/components/resources/Recipe.astro b/src/components/resources/Recipe.astro
index 5f6526c..5306128 100644
--- a/src/components/resources/Recipe.astro
+++ b/src/components/resources/Recipe.astro
@@ -17,7 +17,7 @@ const instructions = resource?.content?.recipeInstructions || [];
Ingredients
{
- ingredients.map((ingredient) => (
+ ingredients.map((ingredient: string) => (
-
))
}
@@ -26,7 +26,7 @@ const instructions = resource?.content?.recipeInstructions || [];
Steps
{
- instructions.map((ingredient) => (
+ instructions.map((ingredient: string) => (
-
))
}
diff --git a/src/helpers/image.ts b/src/helpers/image.ts
index 8b01192..c66bb91 100644
--- a/src/helpers/image.ts
+++ b/src/helpers/image.ts
@@ -3,6 +3,9 @@ import ExifReader from "exifreader";
import type { ImageMetadata } from "astro";
import { readFile } from "node:fs/promises";
import sharp from "sharp";
+import { createHash } from "node:crypto";
+import { promises as fs } from "node:fs";
+import path from "node:path";
export async function generateThumbHash(
buffer: ArrayBuffer,
@@ -81,3 +84,36 @@ export async function getExifData(buffer: ArrayBuffer) {
return hasExif ? out : undefined;
}
+
+const CACHE_DIR = path.join(process.cwd(), 'node_modules', '.astro', 'image-cache');
+
+export async function getProcessedImage(image: ImageMetadata) {
+ const buffer = await getImageBuffer(image);
+ if (!buffer) {
+ return { thumbhash: undefined, exif: undefined };
+ }
+
+ const hash = createHash('sha256').update(new Uint8Array(buffer)).digest('hex');
+ const cacheFile = path.join(CACHE_DIR, `${hash}.json`);
+
+ try {
+ const cachedData = await fs.readFile(cacheFile, 'utf-8');
+ return JSON.parse(cachedData);
+ } catch (e) {
+ if (e.code !== 'ENOENT') {
+ console.error("Failed to read from image cache:", e);
+ }
+ }
+
+ const thumbhash = await generateThumbHash(buffer);
+ const exif = await getExifData(buffer);
+
+ try {
+ await fs.mkdir(CACHE_DIR, { recursive: true });
+ await fs.writeFile(cacheFile, JSON.stringify({ thumbhash, exif }), 'utf-8');
+ } catch (writeError) {
+ console.error("Failed to write to image cache:", writeError);
+ }
+
+ return { thumbhash, exif };
+}
diff --git a/src/helpers/memorium.ts b/src/helpers/memorium.ts
index 2183ebf..36282e9 100644
--- a/src/helpers/memorium.ts
+++ b/src/helpers/memorium.ts
@@ -34,7 +34,7 @@ export async function listResource(
if (json.type == "dir") {
return {
...json,
- content: json.content.filter((res) =>
+ content: json.content.filter((res: MemoriumEntry) =>
res.mime === "application/markdown"
),
};
diff --git a/src/pages/resources/[resourceType]/index.astro b/src/pages/resources/[resourceType]/index.astro
index 873e534..a8fb20c 100644
--- a/src/pages/resources/[resourceType]/index.astro
+++ b/src/pages/resources/[resourceType]/index.astro
@@ -29,7 +29,7 @@ export async function getStaticPaths() {
});
}
-function isValidResource(res) {
+function isValidResource(res: any) {
return !!res?.content?._type;
}
---
@@ -39,7 +39,7 @@ function isValidResource(res) {
{t(`${resourceType as "articles"}.description`)}
{
resources.content
- .filter((res) => isValidResource(res))
+ .filter((res: any) => isValidResource(res))
.map((resource: any) => (