takumi-js 2.14.0 → 2.15.1

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.
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_render = require("./render-B2cdtVWB.cjs");
2
+ const require_render = require("./render-BmM58jcW.cjs");
3
+ exports.measure = require_render.measure;
3
4
  exports.render = require_render.render;
4
5
  exports.renderAnimation = require_render.renderAnimation;
5
6
  exports.renderSvg = require_render.renderSvg;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RenderOptions, c as renderAnimation, i as RenderInput, l as renderSvg, n as ImagesInput, o as RenderSvgOptions, r as RenderAnimationOptions, s as render, t as AnimationScene } from "./render-BIjyc8uU.cjs";
1
+ import { a as RenderOptions, c as render, i as RenderInput, l as renderAnimation, n as ImagesInput, o as RenderSvgOptions, r as RenderAnimationOptions, s as measure, t as AnimationScene, u as renderSvg } from "./render-DRoDMAA1.cjs";
2
2
  import { AnimationOutputFormat, DitheringAlgorithm, Font, FontDetails, FontLoader, ImageSource, Keyframes, KeyframesMap, KeyframesRuleList, MeasuredNode, MeasuredTextRun, OutputFormat } from "@takumi-rs/core";
3
3
  import { AnimationRule, ContainerNode, CssInput, Declarations, FetchOptions, ImageNode, LayerRule, MediaRule, Node, NodeAttributes, NodeMetadata, ReactElementLike, RgbaImage, StyleRule, SupportsRule, TextNode } from "@takumi-rs/helpers";
4
4
  //#region src/glyph-cache.d.ts
@@ -24,4 +24,4 @@ declare module "react" {
24
24
  }
25
25
  }
26
26
  //#endregion
27
- export { type AnimationOutputFormat, type AnimationRule, type AnimationScene, type ContainerNode, type CssInput, type Declarations, type DitheringAlgorithm, type FetchOptions, type Font, type FontDetails, type FontLoader, type ImageNode, type ImageSource, type ImagesInput, type Keyframes, type KeyframesMap, type KeyframesRuleList, type LayerRule, type MeasuredNode, type MeasuredTextRun, type MediaRule, type Node, type NodeAttributes, type NodeMetadata, type OutputFormat, type ReactElementLike, type RenderAnimationOptions, type RenderInput, type RenderOptions, type RenderSvgOptions, type RgbaImage, type StyleRule, type SupportsRule, type TextNode, render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
27
+ export { type AnimationOutputFormat, type AnimationRule, type AnimationScene, type ContainerNode, type CssInput, type Declarations, type DitheringAlgorithm, type FetchOptions, type Font, type FontDetails, type FontLoader, type ImageNode, type ImageSource, type ImagesInput, type Keyframes, type KeyframesMap, type KeyframesRuleList, type LayerRule, type MeasuredNode, type MeasuredTextRun, type MediaRule, type Node, type NodeAttributes, type NodeMetadata, type OutputFormat, type ReactElementLike, type RenderAnimationOptions, type RenderInput, type RenderOptions, type RenderSvgOptions, type RgbaImage, type StyleRule, type SupportsRule, type TextNode, measure, render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as RenderOptions, c as renderAnimation, i as RenderInput, l as renderSvg, n as ImagesInput, o as RenderSvgOptions, r as RenderAnimationOptions, s as render, t as AnimationScene } from "./render-C-wS8FET.mjs";
1
+ import { a as RenderOptions, c as render, i as RenderInput, l as renderAnimation, n as ImagesInput, o as RenderSvgOptions, r as RenderAnimationOptions, s as measure, t as AnimationScene, u as renderSvg } from "./render-D36x-iF4.mjs";
2
2
  import { AnimationRule, ContainerNode, CssInput, Declarations, FetchOptions, ImageNode, LayerRule, MediaRule, Node, NodeAttributes, NodeMetadata, ReactElementLike, RgbaImage, StyleRule, SupportsRule, TextNode } from "@takumi-rs/helpers";
3
3
  import { AnimationOutputFormat, DitheringAlgorithm, Font, FontDetails, FontLoader, ImageSource, Keyframes, KeyframesMap, KeyframesRuleList, MeasuredNode, MeasuredTextRun, OutputFormat } from "@takumi-rs/core";
4
4
  //#region src/glyph-cache.d.ts
@@ -24,4 +24,4 @@ declare module "react" {
24
24
  }
25
25
  }
26
26
  //#endregion
27
- export { type AnimationOutputFormat, type AnimationRule, type AnimationScene, type ContainerNode, type CssInput, type Declarations, type DitheringAlgorithm, type FetchOptions, type Font, type FontDetails, type FontLoader, type ImageNode, type ImageSource, type ImagesInput, type Keyframes, type KeyframesMap, type KeyframesRuleList, type LayerRule, type MeasuredNode, type MeasuredTextRun, type MediaRule, type Node, type NodeAttributes, type NodeMetadata, type OutputFormat, type ReactElementLike, type RenderAnimationOptions, type RenderInput, type RenderOptions, type RenderSvgOptions, type RgbaImage, type StyleRule, type SupportsRule, type TextNode, render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
27
+ export { type AnimationOutputFormat, type AnimationRule, type AnimationScene, type ContainerNode, type CssInput, type Declarations, type DitheringAlgorithm, type FetchOptions, type Font, type FontDetails, type FontLoader, type ImageNode, type ImageSource, type ImagesInput, type Keyframes, type KeyframesMap, type KeyframesRuleList, type LayerRule, type MeasuredNode, type MeasuredTextRun, type MediaRule, type Node, type NodeAttributes, type NodeMetadata, type OutputFormat, type ReactElementLike, type RenderAnimationOptions, type RenderInput, type RenderOptions, type RenderSvgOptions, type RgbaImage, type StyleRule, type SupportsRule, type TextNode, measure, render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { i as setGlyphCacheMaxBytes, n as renderAnimation, r as renderSvg, t as render } from "./render-B1HYpcq6.mjs";
2
- export { render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
1
+ import { a as setGlyphCacheMaxBytes, i as renderSvg, n as render, r as renderAnimation, t as measure } from "./render-DNAu8Luv.mjs";
2
+ export { measure, render, renderAnimation, renderSvg, setGlyphCacheMaxBytes };
@@ -113,6 +113,24 @@ function mergeCss(options, extra) {
113
113
  if (options?.stylesheets !== void 0) warnStylesheetsDeprecated();
114
114
  return [...options?.css !== void 0 ? isCssList(options.css) ? options.css : [options.css] : options?.stylesheets ?? [], ...extra];
115
115
  }
116
+ /** Resolves the renderer, node tree, and backend options, images and CSS merged in, a single scene needs. */
117
+ async function prepareScene(element, options) {
118
+ options?.signal?.throwIfAborted();
119
+ const renderer = await resolveRenderer(options);
120
+ const { node, css } = await resolveContent(element, options);
121
+ const images = await collectImages(node, options);
122
+ options?.signal?.throwIfAborted();
123
+ const { css: _, stylesheets: _alias, ...forward } = options ?? {};
124
+ return {
125
+ renderer,
126
+ node,
127
+ options: {
128
+ ...forward,
129
+ images,
130
+ css: mergeCss(options, css)
131
+ }
132
+ };
133
+ }
116
134
  /**
117
135
  * Renders a React element, HTML string, or Takumi node tree into an image.
118
136
  *
@@ -134,17 +152,27 @@ function mergeCss(options, extra) {
134
152
  * @returns A promise that resolves to the rendered image data (Buffer/Uint8Array).
135
153
  */
136
154
  async function render(element, options) {
137
- options?.signal?.throwIfAborted();
138
- const renderer = await resolveRenderer(options);
139
- const { node, css: extractedCss } = await resolveContent(element, options);
140
- const images = await collectImages(node, options);
141
- options?.signal?.throwIfAborted();
142
- const { css: _, stylesheets: _alias, ...forward } = options ?? {};
143
- return renderer.render(node, {
144
- ...forward,
145
- images,
146
- css: mergeCss(options, extractedCss)
147
- });
155
+ const scene = await prepareScene(element, options);
156
+ return scene.renderer.render(scene.node, scene.options);
157
+ }
158
+ /**
159
+ * Lays out a React element, HTML string, or Takumi node tree without painting it.
160
+ *
161
+ * Same input handling, CSS, emoji, and image pipeline as {@link render}, on the same default
162
+ * renderer, so fonts registered for rendering measure too.
163
+ *
164
+ * @example
165
+ * ```tsx
166
+ * import { measure } from "takumi-js";
167
+ *
168
+ * const { width, height } = await measure(<span tw="text-xl">Hello World</span>);
169
+ * ```
170
+ *
171
+ * @returns A promise that resolves to the measured node tree.
172
+ */
173
+ async function measure(element, options) {
174
+ const scene = await prepareScene(element, options);
175
+ return scene.renderer.measure(scene.node, scene.options);
148
176
  }
149
177
  /**
150
178
  * Renders a React element, HTML string, or Takumi node tree into a vector SVG
@@ -167,17 +195,8 @@ async function render(element, options) {
167
195
  * @returns A promise that resolves to the SVG document string.
168
196
  */
169
197
  async function renderSvg(element, options) {
170
- options?.signal?.throwIfAborted();
171
- const renderer = await resolveRenderer(options);
172
- const { node, css: extractedCss } = await resolveContent(element, options);
173
- const images = await collectImages(node, options);
174
- options?.signal?.throwIfAborted();
175
- const { css: _, stylesheets: _alias, ...forward } = options ?? {};
176
- return renderer.renderSvg(node, {
177
- ...forward,
178
- images,
179
- css: mergeCss(options, extractedCss)
180
- });
198
+ const scene = await prepareScene(element, options);
199
+ return scene.renderer.renderSvg(scene.node, scene.options);
181
200
  }
182
201
  /**
183
202
  * Renders a sequence of scenes into an animated image (WebP / APNG / GIF).
@@ -229,6 +248,12 @@ async function renderAnimation(options) {
229
248
  });
230
249
  }
231
250
  //#endregion
251
+ Object.defineProperty(exports, "measure", {
252
+ enumerable: true,
253
+ get: function() {
254
+ return measure;
255
+ }
256
+ });
232
257
  Object.defineProperty(exports, "render", {
233
258
  enumerable: true,
234
259
  get: function() {
@@ -99,6 +99,22 @@ type RenderInput = ReactNode | ReactElementLike | Node | string;
99
99
  * @returns A promise that resolves to the rendered image data (Buffer/Uint8Array).
100
100
  */
101
101
  declare function render(element: RenderInput, options?: RenderOptions): Promise<Buffer<ArrayBuffer> | Uint8Array<ArrayBuffer>>;
102
+ /**
103
+ * Lays out a React element, HTML string, or Takumi node tree without painting it.
104
+ *
105
+ * Same input handling, CSS, emoji, and image pipeline as {@link render}, on the same default
106
+ * renderer, so fonts registered for rendering measure too.
107
+ *
108
+ * @example
109
+ * ```tsx
110
+ * import { measure } from "takumi-js";
111
+ *
112
+ * const { width, height } = await measure(<span tw="text-xl">Hello World</span>);
113
+ * ```
114
+ *
115
+ * @returns A promise that resolves to the measured node tree.
116
+ */
117
+ declare function measure(element: RenderInput, options?: RenderOptions): Promise<napi.MeasuredNode>;
102
118
  /**
103
119
  * Renders a React element, HTML string, or Takumi node tree into a vector SVG
104
120
  * document string.
@@ -146,4 +162,4 @@ declare function renderSvg(element: RenderInput, options?: RenderSvgOptions): Pr
146
162
  */
147
163
  declare function renderAnimation(options: RenderAnimationOptions): Promise<Buffer<ArrayBuffer> | Uint8Array<ArrayBuffer>>;
148
164
  //#endregion
149
- export { RenderOptions as a, renderAnimation as c, RenderInput as i, renderSvg as l, ImagesInput as n, RenderSvgOptions as o, RenderAnimationOptions as r, render as s, AnimationScene as t };
165
+ export { RenderOptions as a, render as c, RenderInput as i, renderAnimation as l, ImagesInput as n, RenderSvgOptions as o, RenderAnimationOptions as r, measure as s, AnimationScene as t, renderSvg as u };
@@ -113,6 +113,24 @@ function mergeCss(options, extra) {
113
113
  if (options?.stylesheets !== void 0) warnStylesheetsDeprecated();
114
114
  return [...options?.css !== void 0 ? isCssList(options.css) ? options.css : [options.css] : options?.stylesheets ?? [], ...extra];
115
115
  }
116
+ /** Resolves the renderer, node tree, and backend options, images and CSS merged in, a single scene needs. */
117
+ async function prepareScene(element, options) {
118
+ options?.signal?.throwIfAborted();
119
+ const renderer = await resolveRenderer(options);
120
+ const { node, css } = await resolveContent(element, options);
121
+ const images = await collectImages(node, options);
122
+ options?.signal?.throwIfAborted();
123
+ const { css: _, stylesheets: _alias, ...forward } = options ?? {};
124
+ return {
125
+ renderer,
126
+ node,
127
+ options: {
128
+ ...forward,
129
+ images,
130
+ css: mergeCss(options, css)
131
+ }
132
+ };
133
+ }
116
134
  /**
117
135
  * Renders a React element, HTML string, or Takumi node tree into an image.
118
136
  *
@@ -134,17 +152,27 @@ function mergeCss(options, extra) {
134
152
  * @returns A promise that resolves to the rendered image data (Buffer/Uint8Array).
135
153
  */
136
154
  async function render(element, options) {
137
- options?.signal?.throwIfAborted();
138
- const renderer = await resolveRenderer(options);
139
- const { node, css: extractedCss } = await resolveContent(element, options);
140
- const images = await collectImages(node, options);
141
- options?.signal?.throwIfAborted();
142
- const { css: _, stylesheets: _alias, ...forward } = options ?? {};
143
- return renderer.render(node, {
144
- ...forward,
145
- images,
146
- css: mergeCss(options, extractedCss)
147
- });
155
+ const scene = await prepareScene(element, options);
156
+ return scene.renderer.render(scene.node, scene.options);
157
+ }
158
+ /**
159
+ * Lays out a React element, HTML string, or Takumi node tree without painting it.
160
+ *
161
+ * Same input handling, CSS, emoji, and image pipeline as {@link render}, on the same default
162
+ * renderer, so fonts registered for rendering measure too.
163
+ *
164
+ * @example
165
+ * ```tsx
166
+ * import { measure } from "takumi-js";
167
+ *
168
+ * const { width, height } = await measure(<span tw="text-xl">Hello World</span>);
169
+ * ```
170
+ *
171
+ * @returns A promise that resolves to the measured node tree.
172
+ */
173
+ async function measure(element, options) {
174
+ const scene = await prepareScene(element, options);
175
+ return scene.renderer.measure(scene.node, scene.options);
148
176
  }
149
177
  /**
150
178
  * Renders a React element, HTML string, or Takumi node tree into a vector SVG
@@ -167,17 +195,8 @@ async function render(element, options) {
167
195
  * @returns A promise that resolves to the SVG document string.
168
196
  */
169
197
  async function renderSvg(element, options) {
170
- options?.signal?.throwIfAborted();
171
- const renderer = await resolveRenderer(options);
172
- const { node, css: extractedCss } = await resolveContent(element, options);
173
- const images = await collectImages(node, options);
174
- options?.signal?.throwIfAborted();
175
- const { css: _, stylesheets: _alias, ...forward } = options ?? {};
176
- return renderer.renderSvg(node, {
177
- ...forward,
178
- images,
179
- css: mergeCss(options, extractedCss)
180
- });
198
+ const scene = await prepareScene(element, options);
199
+ return scene.renderer.renderSvg(scene.node, scene.options);
181
200
  }
182
201
  /**
183
202
  * Renders a sequence of scenes into an animated image (WebP / APNG / GIF).
@@ -229,4 +248,4 @@ async function renderAnimation(options) {
229
248
  });
230
249
  }
231
250
  //#endregion
232
- export { setGlyphCacheMaxBytes as i, renderAnimation as n, renderSvg as r, render as t };
251
+ export { setGlyphCacheMaxBytes as a, renderSvg as i, render as n, renderAnimation as r, measure as t };
@@ -99,6 +99,22 @@ type RenderInput = ReactNode | ReactElementLike | Node | string;
99
99
  * @returns A promise that resolves to the rendered image data (Buffer/Uint8Array).
100
100
  */
101
101
  declare function render(element: RenderInput, options?: RenderOptions): Promise<Buffer<ArrayBuffer> | Uint8Array<ArrayBuffer>>;
102
+ /**
103
+ * Lays out a React element, HTML string, or Takumi node tree without painting it.
104
+ *
105
+ * Same input handling, CSS, emoji, and image pipeline as {@link render}, on the same default
106
+ * renderer, so fonts registered for rendering measure too.
107
+ *
108
+ * @example
109
+ * ```tsx
110
+ * import { measure } from "takumi-js";
111
+ *
112
+ * const { width, height } = await measure(<span tw="text-xl">Hello World</span>);
113
+ * ```
114
+ *
115
+ * @returns A promise that resolves to the measured node tree.
116
+ */
117
+ declare function measure(element: RenderInput, options?: RenderOptions): Promise<napi.MeasuredNode>;
102
118
  /**
103
119
  * Renders a React element, HTML string, or Takumi node tree into a vector SVG
104
120
  * document string.
@@ -146,4 +162,4 @@ declare function renderSvg(element: RenderInput, options?: RenderSvgOptions): Pr
146
162
  */
147
163
  declare function renderAnimation(options: RenderAnimationOptions): Promise<Buffer<ArrayBuffer> | Uint8Array<ArrayBuffer>>;
148
164
  //#endregion
149
- export { RenderOptions as a, renderAnimation as c, RenderInput as i, renderSvg as l, ImagesInput as n, RenderSvgOptions as o, RenderAnimationOptions as r, render as s, AnimationScene as t };
165
+ export { RenderOptions as a, render as c, RenderInput as i, renderAnimation as l, ImagesInput as n, RenderSvgOptions as o, RenderAnimationOptions as r, measure as s, AnimationScene as t, renderSvg as u };
package/dist/response.cjs CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_render = require("./render-B2cdtVWB.cjs");
5
+ const require_render = require("./render-BmM58jcW.cjs");
6
6
  //#region src/response/index.ts
7
7
  const contentTypeMap = {
8
8
  png: "image/png",
@@ -15,7 +15,8 @@ function defaultErrorHandler(error) {
15
15
  console.error("Failed to render image.");
16
16
  console.error(error);
17
17
  }
18
- function buildImageResponse(element, options) {
18
+ /** Streams the rendered image; `ready` settles once the render finishes or fails. */
19
+ function renderStream(element, options) {
19
20
  let resolveReady;
20
21
  let rejectReady;
21
22
  const ready = new Promise((resolve, reject) => {
@@ -23,30 +24,21 @@ function buildImageResponse(element, options) {
23
24
  rejectReady = reject;
24
25
  });
25
26
  ready.catch(() => {});
26
- const stream = new ReadableStream({ async start(controller) {
27
- try {
28
- const image = await require_render.render(element, options);
29
- controller.enqueue(image);
30
- controller.close();
31
- resolveReady();
32
- } catch (error) {
33
- controller.error(error);
34
- rejectReady(error);
35
- await (options?.onError ?? defaultErrorHandler)(error);
36
- }
37
- } });
38
- const headers = new Headers(options?.headers);
39
- if (!headers.get("content-type")) headers.set("content-type", contentTypeMap[options?.format ?? "png"]);
40
- const response = new Response(stream, {
41
- headers,
42
- status: options?.status,
43
- statusText: options?.statusText
44
- });
45
- return Object.defineProperty(response, "ready", {
46
- enumerable: false,
47
- value: ready,
48
- writable: false
49
- });
27
+ return {
28
+ stream: new ReadableStream({ async start(controller) {
29
+ try {
30
+ const image = await require_render.render(element, options);
31
+ controller.enqueue(image);
32
+ controller.close();
33
+ resolveReady();
34
+ } catch (error) {
35
+ controller.error(error);
36
+ rejectReady(error);
37
+ await (options?.onError ?? defaultErrorHandler)(error);
38
+ }
39
+ } }),
40
+ ready
41
+ };
50
42
  }
51
43
  /**
52
44
  * A universal ImageResponse class for generating images in API routes.
@@ -74,9 +66,15 @@ function buildImageResponse(element, options) {
74
66
  var ImageResponse = class extends Response {
75
67
  ready;
76
68
  constructor(component, options) {
77
- const response = buildImageResponse(component, options);
78
- super(response.body, response);
79
- this.ready = response.ready;
69
+ const { stream, ready } = renderStream(component, options);
70
+ const headers = new Headers(options?.headers);
71
+ if (!headers.get("content-type")) headers.set("content-type", contentTypeMap[options?.format ?? "png"]);
72
+ super(stream, {
73
+ headers,
74
+ status: options?.status,
75
+ statusText: options?.statusText
76
+ });
77
+ this.ready = ready;
80
78
  }
81
79
  };
82
80
  //#endregion
@@ -1,4 +1,4 @@
1
- import { a as RenderOptions, i as RenderInput } from "./render-BIjyc8uU.cjs";
1
+ import { a as RenderOptions, i as RenderInput } from "./render-DRoDMAA1.cjs";
2
2
  //#region src/response/index.d.ts
3
3
  type ImageResponseResult = Response & {
4
4
  readonly ready: Promise<void>;
@@ -1,4 +1,4 @@
1
- import { a as RenderOptions, i as RenderInput } from "./render-C-wS8FET.mjs";
1
+ import { a as RenderOptions, i as RenderInput } from "./render-D36x-iF4.mjs";
2
2
  //#region src/response/index.d.ts
3
3
  type ImageResponseResult = Response & {
4
4
  readonly ready: Promise<void>;
package/dist/response.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as render } from "./render-B1HYpcq6.mjs";
1
+ import { n as render } from "./render-DNAu8Luv.mjs";
2
2
  //#region src/response/index.ts
3
3
  const contentTypeMap = {
4
4
  png: "image/png",
@@ -11,7 +11,8 @@ function defaultErrorHandler(error) {
11
11
  console.error("Failed to render image.");
12
12
  console.error(error);
13
13
  }
14
- function buildImageResponse(element, options) {
14
+ /** Streams the rendered image; `ready` settles once the render finishes or fails. */
15
+ function renderStream(element, options) {
15
16
  let resolveReady;
16
17
  let rejectReady;
17
18
  const ready = new Promise((resolve, reject) => {
@@ -19,30 +20,21 @@ function buildImageResponse(element, options) {
19
20
  rejectReady = reject;
20
21
  });
21
22
  ready.catch(() => {});
22
- const stream = new ReadableStream({ async start(controller) {
23
- try {
24
- const image = await render(element, options);
25
- controller.enqueue(image);
26
- controller.close();
27
- resolveReady();
28
- } catch (error) {
29
- controller.error(error);
30
- rejectReady(error);
31
- await (options?.onError ?? defaultErrorHandler)(error);
32
- }
33
- } });
34
- const headers = new Headers(options?.headers);
35
- if (!headers.get("content-type")) headers.set("content-type", contentTypeMap[options?.format ?? "png"]);
36
- const response = new Response(stream, {
37
- headers,
38
- status: options?.status,
39
- statusText: options?.statusText
40
- });
41
- return Object.defineProperty(response, "ready", {
42
- enumerable: false,
43
- value: ready,
44
- writable: false
45
- });
23
+ return {
24
+ stream: new ReadableStream({ async start(controller) {
25
+ try {
26
+ const image = await render(element, options);
27
+ controller.enqueue(image);
28
+ controller.close();
29
+ resolveReady();
30
+ } catch (error) {
31
+ controller.error(error);
32
+ rejectReady(error);
33
+ await (options?.onError ?? defaultErrorHandler)(error);
34
+ }
35
+ } }),
36
+ ready
37
+ };
46
38
  }
47
39
  /**
48
40
  * A universal ImageResponse class for generating images in API routes.
@@ -70,9 +62,15 @@ function buildImageResponse(element, options) {
70
62
  var ImageResponse = class extends Response {
71
63
  ready;
72
64
  constructor(component, options) {
73
- const response = buildImageResponse(component, options);
74
- super(response.body, response);
75
- this.ready = response.ready;
65
+ const { stream, ready } = renderStream(component, options);
66
+ const headers = new Headers(options?.headers);
67
+ if (!headers.get("content-type")) headers.set("content-type", contentTypeMap[options?.format ?? "png"]);
68
+ super(stream, {
69
+ headers,
70
+ status: options?.status,
71
+ statusText: options?.statusText
72
+ });
73
+ this.ready = ready;
76
74
  }
77
75
  };
78
76
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "takumi-js",
3
- "version": "2.14.0",
3
+ "version": "2.15.1",
4
4
  "description": "Render OG images from JSX, HTML, and CSS. No headless browser.",
5
5
  "keywords": [
6
6
  "animated-webp",
@@ -238,9 +238,9 @@
238
238
  "publish-lint": "attw --pack . && publint --strict ."
239
239
  },
240
240
  "dependencies": {
241
- "@takumi-rs/core": "2.14.0",
242
- "@takumi-rs/helpers": "2.14.0",
243
- "@takumi-rs/wasm": "2.14.0"
241
+ "@takumi-rs/core": "2.15.1",
242
+ "@takumi-rs/helpers": "2.15.1",
243
+ "@takumi-rs/wasm": "2.15.1"
244
244
  },
245
245
  "devDependencies": {
246
246
  "@types/bun": "^1.4.1",