Skip to content

fix(deps): update dependency @takumi-rs/image-response to v2#11

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-takumi
Open

fix(deps): update dependency @takumi-rs/image-response to v2#11
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-takumi

Conversation

@renovate

@renovate renovate Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@takumi-rs/image-response ^1.1.2^2.0.0 age confidence

Release Notes

kane50613/takumi (@​takumi-rs/image-response)

v2.0.3

Select the WASM backend under the unwasm condition

Nitro sets unwasm on every preset, including Node, so takumi-js resolves
#backend to WASM there instead of the native addon a WebContainer host
(StackBlitz, CodeSandbox) can't load. Set exportConditions: ["!unwasm"] to keep
the native bindings on the Node preset.

v2.0.2

Accept a promise in the fonts option

fonts now takes Promise<FontLoader[]> as well as the plain list, so
googleFonts results pass straight through without await.

Extend the embedded font weight axis to 800

The embedded last-resort Geist subset now covers weights 400 to 800.

Accept a families array in googleFonts

Pass the families directly instead of wrapping them in an options object:
googleFonts(["Inter", "Noto Sans JP"]). The object form stays for text,
display, and the other options.

v2.0.1

Default the Google Fonts CSS cache

googleFonts now caches the CSS metadata process-wide when no cache is
passed, so callers who omit it still fetch each URL once. Pass your own Map
to scope the cache, or a fresh one per call to opt out.

v2.0.0

Make the embedded font a true last resort

Both bindings now embed one font: a Latin Geist subset with a 400 to 700
weight axis (Geist Mono and Manrope are gone). It no longer claims the
sans-serif generic family and always sorts after registered fonts in
fallback selection, so generic families and unstyled text resolve to the fonts
you load. The new FontResource::last_resort marks a font's families to sort
after every normal registration.

Cap animation frame rate per format

Browsers clamp any animation frame of 10ms or less to 100ms, so a high frame
rate stalls instead of playing fast. write_animation now rejects a frame rate
above AnimationFormat::max_fps with the new AnimationFrameRateTooHigh error:
90 fps for WebP and APNG, 50 fps for GIF (centisecond delays). The napi and WASM
renderAnimation bindings surface the error.

Apply structured keyframes in renderAnimation

renderAnimation accepted a keyframes option but never registered it, so
structured keyframes animated with render yet stayed static in animations. It
now extends the stylesheet with them like the other entry points.

Fix buffer pool bucket capacity invariant

Release now buckets a buffer by the floor power of two its capacity guarantees,
and acquire_dirty reserves before set_len. A pooled buffer can no longer be
lengthened past its allocation.

Skip mask copies and per-pixel mask lookups in canvas fast paths

Borrow the combined constraint mask directly when it already matches the
canvas viewport instead of copying it per draw, and hoist mask lookups out of
the per-pixel blit loops. Output is unchanged.

Make subset-group font selection deterministic

Subsets registered under one logical family (via FontResource::subset_of) were kept
in registration order. Callers commonly register fonts concurrently, so that order — and
therefore which subset won for a codepoint covered by more than one (e.g. overlapping
weight subsets, where the loser is faux-bolded) — varied per process. Identical input
could render to different bytes run to run.

Subsets are now held in a BTreeSet, ordered by their family name, so expansion and
selection no longer depend on registration timing. Same input renders identically.

Shrink the published binaries

Size-optimize the layout and shaping crates that never run per pixel, cutting
the published WASM and native binary size.

Share the renderer facade between the napi and wasm bindings

The napi and wasm Renderer wrappers now build on a shared prepareRenderInput
helper in @takumi-rs/helpers/renderer, so their option types and render bodies
live in one place. Both backends check signal before and after resolving
fonts and images: on native, an already-aborted signal now throws before any
resource fetch.

Fix gradient stop snapping panic for oversized stop lists

Gradients with more color stops than the LUT can hold no longer panic. The
sample-index clamp and normalization passes stay within LUT bounds.

Reuse per-scene state across animation frames

Compute each scene's font snapshot once and share its image and stylesheet
handles across frames instead of re-snapshotting and deep-cloning the whole
option tree per frame. Frame output is unchanged.

Remove encodeFrames

Renderer.encodeFrames and its EncodeFramesOptions / AnimationFrameSource
types are gone. renderAnimation covers scene-based animation; pre-rendered
frame encoding had no callers.

Replace fetchResources/extractResourceUrls with prepareImages

@takumi-rs/helpers exports prepareImages({ node, sources?, fetchCache?, fetch?, timeout? }),
which collects a node tree's remote images and fetches the ones not already supplied. Pass a
fetchCache (a Map<string, Promise<ArrayBuffer>>, or any Map-like store) to coalesce
concurrent fetches of the same URL and reuse the bytes across renders; a failed fetch is
evicted so a later call retries.

The extractResourceUrls and fetchResources helpers are removed. The images render option
takes the same group form: { sources, fetchCache, fetch, timeout }.

Stream animation frames straight into the encoder

Add write_animation, which renders a timeline and feeds each frame to the
encoder as it arrives, holding one raw frame at a time instead of the whole
sequence. Both the napi and WASM renderAnimation bindings use it, so a high
frame rate or a long duration no longer exhausts memory. On native the WebP
encoder still runs frames in parallel, now over bounded chunks. The WASM WebP
encoder now merges runs of identical frames like the native one, so a static or
slow animation encodes and stores far less. The eager render_animation +
write_animated_* path stays for callers that want every frame at once.

Guard shadow and blur buffer sizing against overflow

Extreme blur radii could overflow the u32 shadow-buffer area and panic or
over-allocate. Sizing now uses saturating math and skips shadows above a 256
Mi-pixel budget.

Type keyframe declarations with csstype instead of DOM's CSSStyleDeclaration

KeyframesMap and KeyframeRule typed each keyframe's declarations as
Record<string, CSSStyleDeclaration>, requiring every CSS property on a single
offset and needing the DOM lib. Declarations are now typed with csstype's
Properties, an optional peer dependency, so a single offset only needs the
properties it sets and consumers without the DOM lib still typecheck.

Accept a bare URL string in fonts

fonts entries can now be a URL string, e.g. fonts: ["https://example.com/Inter.woff2"].
The bytes are fetched on demand and keyed by the URL; family name, weight, and style come
from the font file. The object form stays for overriding those. Adds fontFromUrl to
@takumi-rs/helpers.

Cap image decode dimensions and GIF frame volume

Decoders reject images beyond 8192x8192 (via image::Limits for PNG and JPEG,
dimension checks for WebP) and GIFs beyond a total-frame pixel budget, stopping
decode-bomb OOM.

Drop the ./wasm export

@takumi-rs/image-response/wasm aliased the same file as the root entry. Import from
@takumi-rs/image-response.

Mark ImageResponse.ready rejection as handled

A failed render no longer crashes the process with an unhandledRejection when
the caller never awaits ready. The failure still reaches the stream and a
caller that does await ready still observes it.

Pin @takumi-rs/* dependencies to the matching release

takumi-js resolved its @takumi-rs/core, @takumi-rs/helpers, and @takumi-rs/wasm
dependencies to an older release than itself, so takumi-js/response imported a helper
the pinned @takumi-rs/helpers did not yet export and failed to load. The internal
dependencies now track the same release as takumi-js.

Keep the format tagged union on render options

render, renderSvg, and renderAnimation used a non-distributive Omit that
collapsed the format/quality/lossless union, so { format: "webp", quality: 80 }
stopped type-checking. A distributive Omit restores it.

Cache the Google Fonts CSS promise

googleFonts's cache now stores the in-flight Promise<string> instead of
the resolved CSS, so concurrent calls for the same URL share one request
instead of each missing and fetching. A failed fetch evicts itself, so the
next call retries. The cache type is now
Pick<Map<string, Promise<string>>, "get" | "set" | "delete">.

Match the Chromium UA stylesheet for default element styles

Parse the relative font keywords bolder/lighter (font-weight) and
larger/smaller (font-size), resolving to the values Chromium uses. Expand
the default element presets to cover lists, sub/sup, ins/del, forms,
details/summary, and search.

Bound remote fetches with byte caps and default timeouts

Remote image, font, and Google Fonts CSS fetches now reject bodies past a byte
cap (maxBytes, default 32 MiB; 2 MiB for CSS) and apply the 5 s timeout to
every fetch, not just images. Set timeout: 0 to disable it. A new allowUrl
hook on FetchOptions skips URLs it rejects.

Add the @takumi-rs/helpers/renderer entrypoint

The shared renderer wrapper backing the napi and wasm bindings is now exported
as @takumi-rs/helpers/renderer.

Fix googleFonts losing your declared family order

googleFonts returned subsets in whatever order Google's css2 response happened to list
@font-face blocks in — not the order families were passed in families. A render with no
explicit fontFamilies falls back to registration order, so a Han-unified codepoint shared by
two requested families (e.g. "Noto Sans TC" and "Noto Sans JP") could pick the wrong one
regardless of how families was ordered. googleFonts now sorts its result to match the
caller's declared order.

Keep elements as containers when children carry no text

An element whose children resolved to a textless iterable (e.g. {[]}) became an
empty text node instead of a container, so its background and other box styles
never painted. Such elements now stay containers.

Shrink and sharpen the Google Fonts family type

Group the ~1940 families by their distinct weight/style/axis shape (152 of them) so
GoogleFontFamily builds a discriminated union over shapes, not families. The shipped
.d.ts drops from ~192 KB to ~58 KB and the checker does ~75% fewer instantiations. The
object form now autocompletes each known family's weight, style, and axes, and still accepts
a name built at runtime. The generator refuses to write a catalog with under 1000 families.

Add baseUrl to googleFonts

googleFonts takes an optional baseUrl, defaulting to Google Fonts, so an API-compatible
css2 mirror can be used instead, e.g. baseUrl: "https://fonts.bunny.net/css2" for Bunny Fonts.

Refactor font_families and lang option type

Now both option takes resolved value instead of raw strings.

Fix fontFamilies order being ignored

fontFamilies only fed the fallback bucket, never the root style, so text
picked whichever registered font resolved first instead of the requested
order. FontFamily's default is now empty instead of a generic sans-serif
token, so an empty root style falls through to the fallback bucket directly.

Seal parley::Layout out of the inline-layout boundary

BuiltInlineLayout::{layout, custom_inline_boxes} are now private; the
measure-only walk moves into BuiltInlineLayout::measure_runs, returning
core-owned MeasuredInlineRun/MeasuredInlineBox (run text borrows the
layout). get_parent_font_metrics, resolve_inline_line_metrics,
resolve_inline_line_states, and scale_text_fit_x are no longer public.

Add takumi-html for parsing HTML into a node tree

New takumi-html crate parses HTML + Tailwind markup into a node tree with
from_html(source, FromHtmlOptions), mirroring the JS fromHtml. The tw,
style, class, id, dir, and lang attributes map to node styling and
metadata; FromHtmlOptions sets the StylePresets table and a max_depth
nesting cap. The takumi umbrella re-exports it under the from-html feature
as takumi::from_html, plus Node::from_html via the FromHtml prelude
trait.

Drop background-blend-mode from the background shorthand

The background shorthand parsed a blend-mode token and reset
background-blend-mode, unlike browsers, where the shorthand touches neither. It
now leaves background-blend-mode alone; set it through the longhand. The
blend_mode field is gone from the Background shorthand value.

Rename the svg feature to svg-source

svg and svg-backend read as the same thing at a glance despite gating
opposite directions (image-source input vs. render output). The umbrella's
input-side feature is now svg-source; svg-backend is unchanged.

Make :lang() actually match

:lang() parsed but never matched, like every other pseudo-class the engine treats as
stateful. It needs no live state, only the lang attribute inherited up the tree, which a
static render already has. It now matches BCP-47 basic filtering (:lang(zh-Hant), comma-separated
ranges, *) against the nearest ancestor-or-self with a lang set — the standards-based way to
route different fonts to different languages on the same page, e.g. :lang(ja) { font-family: "Noto Sans JP" } alongside :lang(zh-Hant) { font-family: "Noto Sans TC" }.

Represent the none/normal initial values of max-* and gaps

max-width and max-height are now a MaxSize value whose initial is None
(unbounded), instead of borrowing Length's auto. column-gap, row-gap, and
the gap shorthand are now a Gap value whose initial is Normal. Rendering is
unchanged — none resolves like the old unbounded default and normal computes
to 0 — but the values now round-trip through to_css as none/normal.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot force-pushed the renovate/major-takumi branch from f4f86be to 2ce6b56 Compare July 14, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants