@ 受影响/图像
来自字节的图像事实, 以及生成图像的缓存 . ImageFacts 从头直接读取 PNG 、 JPEG 、 GIF 、 WebP 或 AVIF 文件的格式、 MIME 类型和像素尺寸, 对于无法读取的图像字节, 则有一个键入失败. ImageCache 答案是“我是否已经从这些参数中生成了图像?” 所以一个建筑停止了重跑一个昂贵的渲染器,比如每跑一次的 Open Graph 牌生成器.
预
1.0.0。 。 。 . 此软件包是@effected/*在稳定基础上建造的工具包 效应v4(effect~4.1.0) 并仍在0.x发展。 稳定效果 制作一个工具箱1.0.0可能,不是自动的。 为了保持你的effect财务报告和审定财务报表@effect/*该工具包在线上构建和测试、安装@effected/pnpm-plugin-effected。 。 。 .稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变
0.x释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前1.0.0可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .
安装
npm install @effected/images effect
pnpm add @effected/images effect
需要节点.js~~24.11.0. effect v4是唯一的对等依赖,也是任何种类的唯一依赖——格式阅读器是内部的.
全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED从ES模块导入.
图像事实
根入是纯:无IO,无服务. ImageFacts.fromBytesResult 是同步引擎,可以使用一个没有效果运行时间的脚本,以及 ImageFacts.fromBytes 改为: Effect。 。 。 .
import { ImageFacts } from "@effected/images";
import { Effect, Result } from "effect";
declare const bytes: Uint8Array;
// Synchronous: a Result, never a throw.
const result = ImageFacts.fromBytesResult(bytes);
if (Result.isSuccess(result)) {
const { format, mimeType, width, height } = result.success; // "png", "image/png", 1200, 630
const file = `card.${result.success.extension}`; // "card.png"; a JPEG is written ".jpg"
}
// Effect: fails with ImageParseError.
const facts = ImageFacts.fromBytes(bytes).pipe(
Effect.catchTag("ImageParseError", (e) => Effect.logWarning(`not an image: ${e.reason}`)),
);
mimeType 是五种媒体类型之一(image/png, (中文(简体) ), image/jpeg, (中文(简体) ), image/gif, (中文(简体) ), image/webp, (中文(简体) ), image/avif),以及 extension 是常规文件扩展名 : jpg 页:1 jpeg,格式名称除外. extension 是从 format,所以它不是被编码的形式的一部分, 以及诸如 { ...facts } 放下枪.
ImageParseError.reason 实值 unrecognized (无已知签字), truncated (一个公认的文件剪短)或 malformed (一个自相矛盾的标题). 读者从不投放任何输入,在读取前检查每个长度,并将JPEG和AVIF行走捆绑在分步预算上.
生成图像缓存
@effected/images/cache 在生成它们的参数产生的密钥下生成的缓存字节. ImageCacheKey.fromParams 通过您对参数进行编码 Schema串起它们 并用 salt ——你的生成器的身份,当它的模板改变,所以每个旧条目都错过时被撞倒.
import { ImageBackend, ImageCache, ImageCacheKey } from "@effected/images/cache";
import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { Effect, Layer, Schema } from "effect";
const CardParams = Schema.Struct({ title: Schema.String, theme: Schema.String });
declare const renderCard: () => Effect.Effect<Uint8Array>; // your renderer
const CacheLive = ImageCache.layer.pipe(
Layer.provide(ImageBackend.layerDirectory({ directory: ".cache/og" })),
);
const program = Effect.gen(function* () {
const cache = yield* ImageCache;
const key = yield* ImageCacheKey.fromParams(
CardParams,
{ title: "Hello", theme: "dark" },
{ salt: "og-card-v3", namespace: "og" },
);
const { bytes, facts, hit } = yield* cache.getOrGenerate(
key,
renderCard, // () => Effect<Uint8Array, E, R> - runs only on a miss
{ accept: ["png"] },
);
return { bytes, width: facts.width, hit };
}).pipe(
Effect.provide(CacheLive),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeCrypto.layerDigest)),
);
getOrGenerate 返回字节,它们的 ImageFacts 以及它是否是一个 hit与 accept,结果为 facts.format 输入为可接受的格式,所以 ["png", "jpeg", "webp"] 给 "png" | "jpeg" | "webp"没有它,每个格式。 不再解析的存储条目, 或格式在外的条目 accept,则被视为错失和覆写。 生成结果为空、无法解析或外部 accept 失败 ImageGenerateError 并永远保存。 后端失败表面为 ImageBackendError;生成器自身的出错通过未变.
保证返回的渲染器
当造物主返回约言时 try 财务报告和审定财务报表 catch 因此,它自己的错误到达了呼叫者:
import { Effect } from "effect";
declare const render: (info: { readonly title: string }) => Promise<Uint8Array>;
declare const info: { readonly title: string };
const generate = () => Effect.tryPromise({ try: () => render(info), catch: (cause) => cause });
一个论点 Effect.tryPromise(() => render(info)) 将拒绝内容覆盖到 UnknownError,因此生成器本身的错误丢失.
关闭缓存
ImageBackend.layerNone 无存储 : get 总是怀念和 set 丢弃. 当缓存被禁用时提供它并保持不变 getOrGenerate 调用; 每次调用都会运行生成器并返回 hit: false。 。 。 .
import { ImageBackend } from "@effected/images/cache";
declare const cachingEnabled: boolean;
const backend = cachingEnabled ? ImageBackend.layerDirectory({ directory: ".cache/og" }) : ImageBackend.layerNone;
关键摘要使用核心 Digest.Digest (单位:千美元)effect/crypto),目录后端使用 FileSystem 财务报告和审定财务报表 Path在节点上, NodeServices.layer 从 @effect/platform-node 提供 FileSystem 财务报告和审定财务报表 Path,以及 NodeCrypto.layerDigest 提供 Digest.Digest· ; Digest.layerWebCrypto 从 effect/crypto 在WebCrypto的运行时间工作.
带上自己的店
ImageBackend 是一个端口,而不是依赖. ImageBackend.layerFrom(key) 适应任何服务 get 财务报告和审定财务报表 set 结构匹配——例如 Cache 从 @effected/store,两个包之间没有边缘:
import { Cache } from "@effected/store";
import { ImageBackend } from "@effected/images/cache";
const StoreBacked = ImageBackend.layerFrom(Cache); // provide Cache underneath
目录后端存储 <directory>/<key>.<ext> 通过临时文件和原子重命名。 它接受和无视 tags。 。 。 .
特征
ImageFacts——存储在文件中的格式,MIME类型,文件扩展名和像素尺寸;同步fromBytesResult和效果fromBytes。 。 。 .ImageExtension编号 :ImageMimeType——推广和传媒类工会.ImageFormat- 字面结合png | jpeg | gif | webp | avif。 。 。 .ImageParseError—— 分析失败reason一旦签字相符format。 。 。 .ImageCacheKey编号 :ImageCacheKeyError——来自已编码参数的内容处理键;故障原因encode, (中文(简体) ),non-json财务报告和审定财务报表digest。 。 。 .ImageBackend编号 :ImageBackendError——存储端口,目录后端,无存储后端和结构适配器;故障原因backend财务报告和审定财务报表unsupported-content-type。 。 。 .ImageCache编号 :ImageGenerateError—— 说getOrGenerate带有可选accept缩小结果格式的格式列表.
SVG,BMP,ICO,TIFF,HEIC,JPEG XL,EXIF取向,图像转换和缓存取出都超出了范围.