MartenStorages::VariantPipeline
Libvips-driven resize pipeline. Pure-functional: takes an input
path + spec, writes a resized image to an output path. No DB.
Service calls this and turns the output into a sibling Attachment
row.
Spec shape:
VariantPipeline::Spec.new(max_dimension: 1500) VariantPipeline::Spec.new(max_dimension: 600, format: "png")
max_dimension is the only resize knob right now — matches
Writebook's original needs (cover thumbnail + picture large).
format is optional per-spec and overrides the configuration-level
default_variant_format for this variant only. Extend with
quality:, crop: etc. as needs arise.
NamedTuple → Struct (review §19): the previous NamedTuple alias
forced every call site to spell every key and made adding fields a
breaking change. The Struct keeps construction kwarg-shaped while
letting us add optional fields without breaking callers. For
back-compat, Spec.from(...) accepts the legacy
{max_dimension: N} NamedTuple shape and is wired into
Service.attach overloads so existing call sites that pass a
Hash(String, NamedTuple(max_dimension: Int32)) keep working.
Instance methods
Resize the image at source_path according to spec. Returns the
path of the written variant file (caller is responsible for
cleanup). Raises Vips::VipsException if the source isn't a
vips-readable image; the caller (Service) catches that and skips
variant generation.