@absolutejs/absolute 0.19.0-beta.187 → 0.19.0-beta.188
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.
|
@@ -203,10 +203,11 @@ var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY = 75, OPTIMIZATIO
|
|
|
203
203
|
const mod = await import(name);
|
|
204
204
|
sharpModule = mod.default ?? mod;
|
|
205
205
|
return sharpModule;
|
|
206
|
-
} catch {
|
|
206
|
+
} catch (err) {
|
|
207
207
|
if (sharpWarned)
|
|
208
208
|
return null;
|
|
209
209
|
sharpWarned = true;
|
|
210
|
+
console.warn("[image] sharp load error:", err);
|
|
210
211
|
console.warn("[image] sharp not installed \u2014 serving unoptimized images. Install with: bun add sharp");
|
|
211
212
|
return null;
|
|
212
213
|
}
|
|
@@ -391,5 +392,5 @@ export {
|
|
|
391
392
|
ImageComponent
|
|
392
393
|
};
|
|
393
394
|
|
|
394
|
-
//# debugId=
|
|
395
|
+
//# debugId=E7519BD03B6B2A5564756E2164756E21
|
|
395
396
|
//# sourceMappingURL=index.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/utils/imageProcessing.ts", "../src/angular/components/image.component.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ImageConfig, ImageFormat, RemotePattern } from '../../types/image';\n\n// ── Constants ──────────────────────────────────────────────────────\n\n/* eslint-disable no-magic-numbers */\nexport const DEFAULT_DEVICE_SIZES = [\n\t640, 750, 828, 1080, 1200, 1920, 2048, 3840\n];\n\nexport const DEFAULT_IMAGE_SIZES = [\n\t16, 32, 48, 64, 96, 128, 256, 384\n];\n\nexport const DEFAULT_QUALITY = 75;\n/* eslint-enable no-magic-numbers */\n\nexport const OPTIMIZATION_ENDPOINT = '/_absolute/image';\n\n// ── Blur Placeholder ───────────────────────────────────────────────\n\nconst BLUR_SIZE = 8;\nconst BLUR_QUALITY = 70;\nconst BLUR_DEVIATION = 20;\n\n// ── Sharp Loading ──────────────────────────────────────────────────\n\nlet sharpModule: unknown = undefined;\nlet sharpLoaded = false;\nlet sharpWarned = false;\n\n// ── Shared Internals ───────────────────────────────────────────────\n\n/** Snap a target width UP to the nearest configured size */\nconst snapToSize = (target: number, sizes: number[]) => {\n\tfor (const size of sizes) {\n\t\tif (size >= target) return size;\n\t}\n\n\treturn sizes[sizes.length - 1] ?? target;\n};\n\n/** Match hostname with wildcard support: \"*.example.com\" matches \"cdn.example.com\" */\nconst matchHostname = (actual: string, pattern: string) => {\n\tif (pattern === actual) return true;\n\n\tif (pattern.startsWith('*.')) {\n\t\tconst suffix = pattern.slice(1); // \".example.com\"\n\n\t\treturn actual.endsWith(suffix) && actual.length > suffix.length;\n\t}\n\n\treturn false;\n};\n\n/** Match pathname with glob prefix: \"/images/**\" matches \"/images/photo.jpg\" */\nconst matchPathname = (actual: string, pattern: string) => {\n\tif (pattern.endsWith('/**')) {\n\t\tconst prefix = pattern.slice(0, -2); // eslint-disable-line no-magic-numbers\n\n\t\treturn actual.startsWith(prefix);\n\t}\n\n\treturn actual === pattern;\n};\n\nconst MIME_MAP: Record<ImageFormat, string> = {\n\tavif: 'image/avif',\n\tjpeg: 'image/jpeg',\n\tpng: 'image/png',\n\twebp: 'image/webp'\n};\n\n/** Convert sharp dynamic import result to a callable factory */\nconst callSharp = (sharpRef: unknown, input: Buffer) => {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions -- sharp is dynamically imported\n\tconst factory = sharpRef as any;\n\n\treturn factory(input);\n};\n\nconst toBuffer = (input: Buffer | ArrayBuffer) => {\n\tif (Buffer.isBuffer(input)) return input;\n\n\treturn Buffer.from(input);\n};\n\n// ── Exports (alphabetically sorted) ────────────────────────────────\n\nexport const buildOptimizedUrl = (\n\tsrc: string,\n\twidth: number,\n\tquality: number,\n\tbasePath = OPTIMIZATION_ENDPOINT\n) =>\n\t`${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`;\n\nexport type CacheMeta = {\n\tcontentType: string;\n\tetag: string;\n\texpireAt: number;\n\tupstreamEtag?: string;\n};\n\nexport const formatToMime = (format: ImageFormat) => MIME_MAP[format];\n\nexport const generateBlurDataURL = async (buffer: Buffer | ArrayBuffer) => {\n\tconst sharp = await tryLoadSharp();\n\n\tif (!sharp) return '';\n\n\tconst tiny: Buffer = await callSharp(sharp, toBuffer(buffer))\n\t\t.resize(BLUR_SIZE, BLUR_SIZE, { fit: 'inside' })\n\t\t.webp({ quality: BLUR_QUALITY })\n\t\t.toBuffer();\n\n\treturn `data:image/webp;base64,${tiny.toString('base64')}`;\n};\n\nexport const generateBlurSvg = (base64Thumbnail: string) => {\n\t// Match Next.js: wrap tiny thumbnail in SVG with Gaussian blur\n\tconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 320\"><filter id=\"b\" color-interpolation-filters=\"sRGB\"><feGaussianBlur stdDeviation=\"${BLUR_DEVIATION}\"/><feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1\"/></filter><image filter=\"url(#b)\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" href=\"${base64Thumbnail}\"/></svg>`;\n\n\tconst encoded = encodeURIComponent(svg);\n\n\treturn `url(\"data:image/svg+xml,${encoded}\")`;\n};\n\nexport const generateSrcSet = (\n\tsrc: string,\n\twidth: number | undefined,\n\tsizes: string | undefined,\n\tconfig?: ImageConfig,\n\tloader?: (params: { quality: number; src: string; width: number }) => string\n) => {\n\tconst quality = config?.quality ?? DEFAULT_QUALITY;\n\n\tconst basePath = config?.path ?? OPTIMIZATION_ENDPOINT;\n\n\tconst buildUrl = loader ?? ((params: { quality: number; src: string; width: number }) =>\n\t\tbuildOptimizedUrl(params.src, params.width, params.quality, basePath));\n\n\tif (sizes) {\n\t\t// With sizes: use all breakpoints with w descriptors\n\t\tconst allSizes = getAllSizes(config);\n\n\t\treturn allSizes\n\t\t\t.map((sizeWidth) => `${buildUrl({ quality, src, width: sizeWidth })} ${sizeWidth}w`)\n\t\t\t.join(', ');\n\t}\n\n\tif (width) {\n\t\t// Without sizes: generate 1x and 2x density descriptors\n\t\tconst allSizes = getAllSizes(config);\n\n\t\tconst w1x = snapToSize(width, allSizes);\n\n\t\tconst w2x = snapToSize(width * 2, allSizes);\n\n\t\treturn `${buildUrl({ quality, src, width: w1x })} 1x, ${buildUrl({ quality, src, width: w2x })} 2x`;\n\t}\n\n\t// No width or sizes — use device sizes with w descriptors\n\tconst deviceSizes = config?.deviceSizes ?? DEFAULT_DEVICE_SIZES;\n\n\treturn deviceSizes\n\t\t.map((sizeWidth) => `${buildUrl({ quality, src, width: sizeWidth })} ${sizeWidth}w`)\n\t\t.join(', ');\n};\n\nexport const getAllSizes = (config?: ImageConfig) => {\n\tconst device = config?.deviceSizes ?? DEFAULT_DEVICE_SIZES;\n\n\tconst image = config?.imageSizes ?? DEFAULT_IMAGE_SIZES;\n\n\treturn [...device, ...image].sort((left, right) => left - right);\n};\n\nexport const getCacheDir = (buildDir: string) => {\n\tconst dir = join(buildDir, '.cache', 'images');\n\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n\treturn dir;\n};\n\nexport const getCacheKey = (\n\turl: string,\n\twidth: number,\n\tquality: number,\n\tformat: string\n) => {\n\tconst hasher = new Bun.CryptoHasher('sha256');\n\n\thasher.update(`${url}|${width}|${quality}|${format}`);\n\n\treturn hasher.digest('hex');\n};\n\nexport const isCacheStale = (meta: CacheMeta) => Date.now() > meta.expireAt;\n\nexport const matchRemotePattern = (\n\turlString: string,\n\tpatterns: RemotePattern[]\n) => {\n\tlet parsed: URL;\n\n\ttry {\n\t\tparsed = new URL(urlString);\n\t} catch {\n\t\treturn false;\n\t}\n\n\treturn patterns.some((pattern) => {\n\t\tif (pattern.protocol && parsed.protocol !== `${pattern.protocol}:`) return false;\n\n\t\tif (!matchHostname(parsed.hostname, pattern.hostname)) return false;\n\n\t\tif (pattern.port && parsed.port !== pattern.port) return false;\n\n\t\tif (pattern.pathname && !matchPathname(parsed.pathname, pattern.pathname)) return false;\n\n\t\treturn true;\n\t});\n};\n\nexport const negotiateFormat = (\n\tacceptHeader: string,\n\tconfiguredFormats: ImageFormat[]\n) => {\n\t// Check configured formats in preference order against Accept header\n\tfor (const format of configuredFormats) {\n\t\tconst mime = MIME_MAP[format];\n\n\t\tif (mime && acceptHeader.includes(mime)) return format;\n\t}\n\n\t// Fallback: if webp is configured and accepted, use it\n\tif (configuredFormats.includes('webp') && acceptHeader.includes('image/webp')) {\n\t\treturn 'webp';\n\t}\n\n\t// Final fallback to jpeg\n\treturn 'jpeg';\n};\n\nconst AVIF_QUALITY_OFFSET = 20;\nconst AVIF_EFFORT = 3;\n\nexport const optimizeImage = async (\n\tbuffer: Buffer | ArrayBuffer,\n\twidth: number,\n\tquality: number,\n\tformat: ImageFormat\n) => {\n\tconst sharp = await tryLoadSharp();\n\n\tif (!sharp) return toBuffer(buffer);\n\n\tconst pipeline = callSharp(sharp, toBuffer(buffer))\n\t\t.rotate()\n\t\t.resize(width, undefined, { withoutEnlargement: true });\n\n\tswitch (format) {\n\t\tcase 'avif':\n\t\t\treturn pipeline\n\t\t\t\t.avif({ effort: AVIF_EFFORT, quality: Math.max(1, quality - AVIF_QUALITY_OFFSET) })\n\t\t\t\t.toBuffer();\n\t\tcase 'jpeg':\n\t\t\treturn pipeline\n\t\t\t\t.jpeg({ mozjpeg: true, quality })\n\t\t\t\t.toBuffer();\n\t\tcase 'png':\n\t\t\treturn pipeline.png({ quality }).toBuffer();\n\t\tcase 'webp':\n\t\t\treturn pipeline.webp({ quality }).toBuffer();\n\t\tdefault:\n\t\t\treturn toBuffer(buffer);\n\t}\n};\n\nexport const readFromCache = (cacheDir: string, cacheKey: string) => {\n\tconst metaPath = join(cacheDir, `${cacheKey}.meta`);\n\n\tconst dataPath = join(cacheDir, `${cacheKey}.data`);\n\n\tif (!existsSync(metaPath) || !existsSync(dataPath)) return null;\n\n\ttry {\n\t\tconst meta: CacheMeta = JSON.parse(readFileSync(metaPath, 'utf-8'));\n\n\t\tconst buffer = readFileSync(dataPath);\n\n\t\treturn { buffer, meta };\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const tryLoadSharp = async () => {\n\tif (sharpLoaded) return sharpModule;\n\n\tsharpLoaded = true;\n\n\ttry {\n\t\t// Dynamic import — sharp is an optional peer dependency\n\t\tconst name = 'sharp';\n\n\t\tconst mod = await import(/* @vite-ignore */ name);\n\n\t\tsharpModule = mod.default ?? mod;\n\n\t\treturn sharpModule;\n\t} catch {\n\t\tif (sharpWarned) return null;\n\n\t\tsharpWarned = true;\n\n\t\tconsole.warn(\n\t\t\t'[image] sharp not installed — serving unoptimized images. Install with: bun add sharp'\n\t\t);\n\n\t\treturn null;\n\t}\n};\n\nexport const writeToCache = (\n\tcacheDir: string,\n\tcacheKey: string,\n\tbuffer: Buffer,\n\tmeta: CacheMeta\n) => {\n\tconst metaPath = join(cacheDir, `${cacheKey}.meta`);\n\n\tconst dataPath = join(cacheDir, `${cacheKey}.data`);\n\n\twriteFileSync(dataPath, buffer);\n\n\twriteFileSync(metaPath, JSON.stringify(meta));\n};\n",
|
|
5
|
+
"import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ImageConfig, ImageFormat, RemotePattern } from '../../types/image';\n\n// ── Constants ──────────────────────────────────────────────────────\n\n/* eslint-disable no-magic-numbers */\nexport const DEFAULT_DEVICE_SIZES = [\n\t640, 750, 828, 1080, 1200, 1920, 2048, 3840\n];\n\nexport const DEFAULT_IMAGE_SIZES = [\n\t16, 32, 48, 64, 96, 128, 256, 384\n];\n\nexport const DEFAULT_QUALITY = 75;\n/* eslint-enable no-magic-numbers */\n\nexport const OPTIMIZATION_ENDPOINT = '/_absolute/image';\n\n// ── Blur Placeholder ───────────────────────────────────────────────\n\nconst BLUR_SIZE = 8;\nconst BLUR_QUALITY = 70;\nconst BLUR_DEVIATION = 20;\n\n// ── Sharp Loading ──────────────────────────────────────────────────\n\nlet sharpModule: unknown = undefined;\nlet sharpLoaded = false;\nlet sharpWarned = false;\n\n// ── Shared Internals ───────────────────────────────────────────────\n\n/** Snap a target width UP to the nearest configured size */\nconst snapToSize = (target: number, sizes: number[]) => {\n\tfor (const size of sizes) {\n\t\tif (size >= target) return size;\n\t}\n\n\treturn sizes[sizes.length - 1] ?? target;\n};\n\n/** Match hostname with wildcard support: \"*.example.com\" matches \"cdn.example.com\" */\nconst matchHostname = (actual: string, pattern: string) => {\n\tif (pattern === actual) return true;\n\n\tif (pattern.startsWith('*.')) {\n\t\tconst suffix = pattern.slice(1); // \".example.com\"\n\n\t\treturn actual.endsWith(suffix) && actual.length > suffix.length;\n\t}\n\n\treturn false;\n};\n\n/** Match pathname with glob prefix: \"/images/**\" matches \"/images/photo.jpg\" */\nconst matchPathname = (actual: string, pattern: string) => {\n\tif (pattern.endsWith('/**')) {\n\t\tconst prefix = pattern.slice(0, -2); // eslint-disable-line no-magic-numbers\n\n\t\treturn actual.startsWith(prefix);\n\t}\n\n\treturn actual === pattern;\n};\n\nconst MIME_MAP: Record<ImageFormat, string> = {\n\tavif: 'image/avif',\n\tjpeg: 'image/jpeg',\n\tpng: 'image/png',\n\twebp: 'image/webp'\n};\n\n/** Convert sharp dynamic import result to a callable factory */\nconst callSharp = (sharpRef: unknown, input: Buffer) => {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions -- sharp is dynamically imported\n\tconst factory = sharpRef as any;\n\n\treturn factory(input);\n};\n\nconst toBuffer = (input: Buffer | ArrayBuffer) => {\n\tif (Buffer.isBuffer(input)) return input;\n\n\treturn Buffer.from(input);\n};\n\n// ── Exports (alphabetically sorted) ────────────────────────────────\n\nexport const buildOptimizedUrl = (\n\tsrc: string,\n\twidth: number,\n\tquality: number,\n\tbasePath = OPTIMIZATION_ENDPOINT\n) =>\n\t`${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`;\n\nexport type CacheMeta = {\n\tcontentType: string;\n\tetag: string;\n\texpireAt: number;\n\tupstreamEtag?: string;\n};\n\nexport const formatToMime = (format: ImageFormat) => MIME_MAP[format];\n\nexport const generateBlurDataURL = async (buffer: Buffer | ArrayBuffer) => {\n\tconst sharp = await tryLoadSharp();\n\n\tif (!sharp) return '';\n\n\tconst tiny: Buffer = await callSharp(sharp, toBuffer(buffer))\n\t\t.resize(BLUR_SIZE, BLUR_SIZE, { fit: 'inside' })\n\t\t.webp({ quality: BLUR_QUALITY })\n\t\t.toBuffer();\n\n\treturn `data:image/webp;base64,${tiny.toString('base64')}`;\n};\n\nexport const generateBlurSvg = (base64Thumbnail: string) => {\n\t// Match Next.js: wrap tiny thumbnail in SVG with Gaussian blur\n\tconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 320\"><filter id=\"b\" color-interpolation-filters=\"sRGB\"><feGaussianBlur stdDeviation=\"${BLUR_DEVIATION}\"/><feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1\"/></filter><image filter=\"url(#b)\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" href=\"${base64Thumbnail}\"/></svg>`;\n\n\tconst encoded = encodeURIComponent(svg);\n\n\treturn `url(\"data:image/svg+xml,${encoded}\")`;\n};\n\nexport const generateSrcSet = (\n\tsrc: string,\n\twidth: number | undefined,\n\tsizes: string | undefined,\n\tconfig?: ImageConfig,\n\tloader?: (params: { quality: number; src: string; width: number }) => string\n) => {\n\tconst quality = config?.quality ?? DEFAULT_QUALITY;\n\n\tconst basePath = config?.path ?? OPTIMIZATION_ENDPOINT;\n\n\tconst buildUrl = loader ?? ((params: { quality: number; src: string; width: number }) =>\n\t\tbuildOptimizedUrl(params.src, params.width, params.quality, basePath));\n\n\tif (sizes) {\n\t\t// With sizes: use all breakpoints with w descriptors\n\t\tconst allSizes = getAllSizes(config);\n\n\t\treturn allSizes\n\t\t\t.map((sizeWidth) => `${buildUrl({ quality, src, width: sizeWidth })} ${sizeWidth}w`)\n\t\t\t.join(', ');\n\t}\n\n\tif (width) {\n\t\t// Without sizes: generate 1x and 2x density descriptors\n\t\tconst allSizes = getAllSizes(config);\n\n\t\tconst w1x = snapToSize(width, allSizes);\n\n\t\tconst w2x = snapToSize(width * 2, allSizes);\n\n\t\treturn `${buildUrl({ quality, src, width: w1x })} 1x, ${buildUrl({ quality, src, width: w2x })} 2x`;\n\t}\n\n\t// No width or sizes — use device sizes with w descriptors\n\tconst deviceSizes = config?.deviceSizes ?? DEFAULT_DEVICE_SIZES;\n\n\treturn deviceSizes\n\t\t.map((sizeWidth) => `${buildUrl({ quality, src, width: sizeWidth })} ${sizeWidth}w`)\n\t\t.join(', ');\n};\n\nexport const getAllSizes = (config?: ImageConfig) => {\n\tconst device = config?.deviceSizes ?? DEFAULT_DEVICE_SIZES;\n\n\tconst image = config?.imageSizes ?? DEFAULT_IMAGE_SIZES;\n\n\treturn [...device, ...image].sort((left, right) => left - right);\n};\n\nexport const getCacheDir = (buildDir: string) => {\n\tconst dir = join(buildDir, '.cache', 'images');\n\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n\treturn dir;\n};\n\nexport const getCacheKey = (\n\turl: string,\n\twidth: number,\n\tquality: number,\n\tformat: string\n) => {\n\tconst hasher = new Bun.CryptoHasher('sha256');\n\n\thasher.update(`${url}|${width}|${quality}|${format}`);\n\n\treturn hasher.digest('hex');\n};\n\nexport const isCacheStale = (meta: CacheMeta) => Date.now() > meta.expireAt;\n\nexport const matchRemotePattern = (\n\turlString: string,\n\tpatterns: RemotePattern[]\n) => {\n\tlet parsed: URL;\n\n\ttry {\n\t\tparsed = new URL(urlString);\n\t} catch {\n\t\treturn false;\n\t}\n\n\treturn patterns.some((pattern) => {\n\t\tif (pattern.protocol && parsed.protocol !== `${pattern.protocol}:`) return false;\n\n\t\tif (!matchHostname(parsed.hostname, pattern.hostname)) return false;\n\n\t\tif (pattern.port && parsed.port !== pattern.port) return false;\n\n\t\tif (pattern.pathname && !matchPathname(parsed.pathname, pattern.pathname)) return false;\n\n\t\treturn true;\n\t});\n};\n\nexport const negotiateFormat = (\n\tacceptHeader: string,\n\tconfiguredFormats: ImageFormat[]\n) => {\n\t// Check configured formats in preference order against Accept header\n\tfor (const format of configuredFormats) {\n\t\tconst mime = MIME_MAP[format];\n\n\t\tif (mime && acceptHeader.includes(mime)) return format;\n\t}\n\n\t// Fallback: if webp is configured and accepted, use it\n\tif (configuredFormats.includes('webp') && acceptHeader.includes('image/webp')) {\n\t\treturn 'webp';\n\t}\n\n\t// Final fallback to jpeg\n\treturn 'jpeg';\n};\n\nconst AVIF_QUALITY_OFFSET = 20;\nconst AVIF_EFFORT = 3;\n\nexport const optimizeImage = async (\n\tbuffer: Buffer | ArrayBuffer,\n\twidth: number,\n\tquality: number,\n\tformat: ImageFormat\n) => {\n\tconst sharp = await tryLoadSharp();\n\n\tif (!sharp) return toBuffer(buffer);\n\n\tconst pipeline = callSharp(sharp, toBuffer(buffer))\n\t\t.rotate()\n\t\t.resize(width, undefined, { withoutEnlargement: true });\n\n\tswitch (format) {\n\t\tcase 'avif':\n\t\t\treturn pipeline\n\t\t\t\t.avif({ effort: AVIF_EFFORT, quality: Math.max(1, quality - AVIF_QUALITY_OFFSET) })\n\t\t\t\t.toBuffer();\n\t\tcase 'jpeg':\n\t\t\treturn pipeline\n\t\t\t\t.jpeg({ mozjpeg: true, quality })\n\t\t\t\t.toBuffer();\n\t\tcase 'png':\n\t\t\treturn pipeline.png({ quality }).toBuffer();\n\t\tcase 'webp':\n\t\t\treturn pipeline.webp({ quality }).toBuffer();\n\t\tdefault:\n\t\t\treturn toBuffer(buffer);\n\t}\n};\n\nexport const readFromCache = (cacheDir: string, cacheKey: string) => {\n\tconst metaPath = join(cacheDir, `${cacheKey}.meta`);\n\n\tconst dataPath = join(cacheDir, `${cacheKey}.data`);\n\n\tif (!existsSync(metaPath) || !existsSync(dataPath)) return null;\n\n\ttry {\n\t\tconst meta: CacheMeta = JSON.parse(readFileSync(metaPath, 'utf-8'));\n\n\t\tconst buffer = readFileSync(dataPath);\n\n\t\treturn { buffer, meta };\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const tryLoadSharp = async () => {\n\tif (sharpLoaded) return sharpModule;\n\n\tsharpLoaded = true;\n\n\ttry {\n\t\t// Dynamic import — sharp is an optional peer dependency\n\t\tconst name = 'sharp';\n\n\t\tconst mod = await import(/* @vite-ignore */ name);\n\n\t\tsharpModule = mod.default ?? mod;\n\n\t\treturn sharpModule;\n\t} catch (err) {\n\t\tif (sharpWarned) return null;\n\n\t\tsharpWarned = true;\n\n\t\tconsole.warn('[image] sharp load error:', err);\n\t\tconsole.warn(\n\t\t\t'[image] sharp not installed — serving unoptimized images. Install with: bun add sharp'\n\t\t);\n\n\t\treturn null;\n\t}\n};\n\nexport const writeToCache = (\n\tcacheDir: string,\n\tcacheKey: string,\n\tbuffer: Buffer,\n\tmeta: CacheMeta\n) => {\n\tconst metaPath = join(cacheDir, `${cacheKey}.meta`);\n\n\tconst dataPath = join(cacheDir, `${cacheKey}.data`);\n\n\twriteFileSync(dataPath, buffer);\n\n\twriteFileSync(metaPath, JSON.stringify(meta));\n};\n",
|
|
6
6
|
"import { Component, computed, input, signal } from '@angular/core';\nimport type { ImageLoader } from '../../../types/image';\nimport {\n\tDEFAULT_QUALITY,\n\tbuildOptimizedUrl,\n\tgenerateBlurSvg,\n\tgenerateSrcSet\n} from '../../utils/imageProcessing';\n\n/** Resolve the blur background CSS value from placeholder config */\nconst resolveBlurBg = (\n\tplaceholderValue: string,\n\tblurDataUrl: string | undefined\n) => {\n\tif (\n\t\ttypeof placeholderValue === 'string' &&\n\t\tplaceholderValue !== 'blur' &&\n\t\tplaceholderValue.startsWith('data:')\n\t) {\n\t\treturn generateBlurSvg(placeholderValue);\n\t}\n\n\tif (blurDataUrl) return generateBlurSvg(blurDataUrl);\n\n\treturn undefined;\n};\n\n@Component({\n\tselector: 'abs-image',\n\tstandalone: true,\n\ttemplate: `\n\t\t@if (priority()) {\n\t\t\t<link\n\t\t\t\trel=\"preload\"\n\t\t\t\tas=\"image\"\n\t\t\t\t[attr.href]=\"resolvedSrc()\"\n\t\t\t\t[attr.imagesrcset]=\"srcSet()\"\n\t\t\t\t[attr.imagesizes]=\"resolvedSizes()\"\n\t\t\t\t[attr.crossorigin]=\"crossOrigin()\"\n\t\t\t/>\n\t\t}\n\t\t@if (fill()) {\n\t\t\t<span style=\"position:relative;overflow:hidden;display:block;width:100%;height:100%\">\n\t\t\t\t<img\n\t\t\t\t\t[alt]=\"alt()\"\n\t\t\t\t\t[src]=\"resolvedSrc()\"\n\t\t\t\t\t[srcset]=\"srcSet()\"\n\t\t\t\t\t[sizes]=\"resolvedSizes()\"\n\t\t\t\t\t[loading]=\"resolvedLoading()\"\n\t\t\t\t\t[class]=\"className()\"\n\t\t\t\t\t[ngStyle]=\"imgStyle()\"\n\t\t\t\t\t[crossOrigin]=\"crossOrigin()\"\n\t\t\t\t\t[referrerPolicy]=\"referrerPolicy()\"\n\t\t\t\t\t[attr.fetchpriority]=\"resolvedFetchPriority()\"\n\t\t\t\t\tdecoding=\"async\"\n\t\t\t\t\t(load)=\"handleLoad($event)\"\n\t\t\t\t\t(error)=\"handleError($event)\"\n\t\t\t\t/>\n\t\t\t</span>\n\t\t} @else {\n\t\t\t<img\n\t\t\t\t[alt]=\"alt()\"\n\t\t\t\t[src]=\"resolvedSrc()\"\n\t\t\t\t[srcset]=\"srcSet()\"\n\t\t\t\t[sizes]=\"resolvedSizes()\"\n\t\t\t\t[width]=\"width()\"\n\t\t\t\t[height]=\"height()\"\n\t\t\t\t[loading]=\"resolvedLoading()\"\n\t\t\t\t[class]=\"className()\"\n\t\t\t\t[ngStyle]=\"imgStyle()\"\n\t\t\t\t[crossOrigin]=\"crossOrigin()\"\n\t\t\t\t[referrerPolicy]=\"referrerPolicy()\"\n\t\t\t\t[attr.fetchpriority]=\"resolvedFetchPriority()\"\n\t\t\t\tdecoding=\"async\"\n\t\t\t\t(load)=\"handleLoad($event)\"\n\t\t\t\t(error)=\"handleError($event)\"\n\t\t\t/>\n\t\t}\n\t`\n})\nexport class ImageComponent {\n\t// ── Inputs ──────────────────────────────────────────────────\n\treadonly alt = input.required<string>();\n\treadonly blurDataURL = input<string>();\n\treadonly className = input<string>();\n\treadonly crossOrigin = input<'anonymous' | 'use-credentials' | ''>();\n\treadonly fetchPriority = input<'high' | 'low' | 'auto'>();\n\treadonly fill = input(false);\n\treadonly height = input<number>();\n\treadonly loader = input<ImageLoader>();\n\treadonly loading = input<'lazy' | 'eager'>('lazy');\n\treadonly onError = input<((event: Event) => void)>();\n\treadonly onLoad = input<((event: Event) => void)>();\n\treadonly overrideSrc = input<string>();\n\treadonly placeholder = input<'blur' | 'empty' | string>('empty');\n\treadonly priority = input(false);\n\treadonly quality = input(DEFAULT_QUALITY);\n\treadonly referrerPolicy = input<string>();\n\treadonly sizes = input<string>();\n\treadonly src = input.required<string>();\n\treadonly style = input<Record<string, string | number>>();\n\treadonly unoptimized = input(false);\n\treadonly width = input<number>();\n\n\t// ── Internal state ──────────────────────────────────────────\n\tprivate readonly blurRemoved = signal(false);\n\n\t// ── Computed ────────────────────────────────────────────────\n\treadonly resolvedSrc = computed(() => {\n\t\tconst override = this.overrideSrc();\n\n\t\tif (override) return override;\n\n\t\tif (this.unoptimized()) return this.src();\n\n\t\tconst loaderFn = this.loader();\n\n\t\tif (loaderFn) return loaderFn({ quality: this.quality(), src: this.src(), width: this.width() ?? 0 });\n\n\t\tconst currentWidth = this.width();\n\n\t\tif (!currentWidth) return buildOptimizedUrl(this.src(), 0, this.quality());\n\n\t\treturn buildOptimizedUrl(this.src(), currentWidth, this.quality());\n\t});\n\n\treadonly srcSet = computed(() =>\n\t\tthis.unoptimized()\n\t\t\t? undefined\n\t\t\t: generateSrcSet(this.src(), this.width(), this.sizes(), undefined, this.loader() ?? undefined)\n\t);\n\n\treadonly resolvedSizes = computed(() =>\n\t\tthis.sizes() ?? (this.fill() ? '100vw' : undefined)\n\t);\n\n\treadonly resolvedLoading = computed(() =>\n\t\tthis.priority() ? 'eager' as const : this.loading()\n\t);\n\n\treadonly resolvedFetchPriority = computed(() =>\n\t\tthis.priority() ? 'high' : this.fetchPriority()\n\t);\n\n\treadonly imgStyle = computed(() => {\n\t\tconst base: Record<string, string | number> = {\n\t\t\t...(this.style() ?? {}),\n\t\t\tcolor: 'transparent'\n\t\t};\n\n\t\tconst hasBlur =\n\t\t\t!this.blurRemoved() &&\n\t\t\t(this.placeholder() === 'blur' ||\n\t\t\t\t(typeof this.placeholder() === 'string' &&\n\t\t\t\t\tthis.placeholder() !== 'empty' &&\n\t\t\t\t\t(this.placeholder() ?? '').startsWith('data:')));\n\n\t\tconst blurValue = hasBlur\n\t\t\t? resolveBlurBg(this.placeholder(), this.blurDataURL())\n\t\t\t: undefined;\n\n\t\tif (blurValue) {\n\t\t\tbase['background-image'] = blurValue;\n\t\t\tbase['background-position'] = 'center';\n\t\t\tbase['background-repeat'] = 'no-repeat';\n\t\t\tbase['background-size'] = 'cover';\n\t\t}\n\n\t\tif (this.fill()) {\n\t\t\tbase.height = '100%';\n\t\t\tbase.inset = '0';\n\t\t\tbase['object-fit'] = 'cover';\n\t\t\tbase.position = 'absolute';\n\t\t\tbase.width = '100%';\n\t\t}\n\n\t\treturn base;\n\t});\n\n\t// ── Event handlers ──────────────────────────────────────────\n\thandleLoad(event: Event) {\n\t\tthis.blurRemoved.set(true);\n\n\t\tconst callback = this.onLoad();\n\n\t\tif (callback) callback(event);\n\t}\n\n\thandleError(event: Event) {\n\t\tconst callback = this.onError();\n\n\t\tif (callback) callback(event);\n\t}\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "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
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "E7519BD03B6B2A5564756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/src/build.js
CHANGED
|
@@ -875,10 +875,11 @@ var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY = 75, OPTIMIZATIO
|
|
|
875
875
|
const mod = await import(name);
|
|
876
876
|
sharpModule = mod.default ?? mod;
|
|
877
877
|
return sharpModule;
|
|
878
|
-
} catch {
|
|
878
|
+
} catch (err) {
|
|
879
879
|
if (sharpWarned)
|
|
880
880
|
return null;
|
|
881
881
|
sharpWarned = true;
|
|
882
|
+
console.warn("[image] sharp load error:", err);
|
|
882
883
|
console.warn("[image] sharp not installed \u2014 serving unoptimized images. Install with: bun add sharp");
|
|
883
884
|
return null;
|
|
884
885
|
}
|
|
@@ -205839,5 +205840,5 @@ export {
|
|
|
205839
205840
|
build
|
|
205840
205841
|
};
|
|
205841
205842
|
|
|
205842
|
-
//# debugId=
|
|
205843
|
+
//# debugId=C1FAD242C7C2E3F464756E2164756E21
|
|
205843
205844
|
//# sourceMappingURL=build.js.map
|