@agent-scope/render 1.0.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 +1555 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +925 -0
- package/dist/index.d.ts +925 -0
- package/dist/index.js +1523 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,925 @@
|
|
|
1
|
+
import * as playwright from 'playwright';
|
|
2
|
+
import { ComplexityClass, ComponentDescriptor } from '@agent-scope/manifest';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Types for the @agent-scope/render package.
|
|
7
|
+
*
|
|
8
|
+
* Shared types plus render-path-specific types for both:
|
|
9
|
+
* - SatoriRenderer: Satori-based path for simple (flexbox-only) components
|
|
10
|
+
* - BrowserPool: Playwright-based path for complex components
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The result produced by either render path (SatoriRenderer or BrowserPool).
|
|
14
|
+
*/
|
|
15
|
+
interface RenderResult {
|
|
16
|
+
/** PNG screenshot as a Buffer. */
|
|
17
|
+
screenshot: Buffer;
|
|
18
|
+
/** Pixel width of the rendered component. */
|
|
19
|
+
width: number;
|
|
20
|
+
/** Pixel height of the rendered component. */
|
|
21
|
+
height: number;
|
|
22
|
+
/** Wall-clock render duration in milliseconds. */
|
|
23
|
+
renderTimeMs: number;
|
|
24
|
+
/**
|
|
25
|
+
* Computed CSS property snapshots keyed by CSS selector or element path.
|
|
26
|
+
* E.g. `{ "root": { "display": "flex" } }` (Satori) or
|
|
27
|
+
* `{ "[data-reactscope-root] > *": { "display": "flex" } }` (Browser)
|
|
28
|
+
*/
|
|
29
|
+
computedStyles: Record<string, Record<string, string>>;
|
|
30
|
+
/** DOM tree and element count (BrowserPool only, when `captureDom` is true). */
|
|
31
|
+
dom?: {
|
|
32
|
+
tree: DOMNode;
|
|
33
|
+
elementCount: number;
|
|
34
|
+
boundingBox: BoundingBox;
|
|
35
|
+
};
|
|
36
|
+
/** Browser console output (BrowserPool only, when `captureConsole` is true). */
|
|
37
|
+
console?: {
|
|
38
|
+
errors: string[];
|
|
39
|
+
warnings: string[];
|
|
40
|
+
logs: string[];
|
|
41
|
+
};
|
|
42
|
+
/** Basic accessibility snapshot (BrowserPool only, when `captureA11y` is true). */
|
|
43
|
+
accessibility?: {
|
|
44
|
+
role: string;
|
|
45
|
+
name: string;
|
|
46
|
+
violations: string[];
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Axis-aligned bounding box in CSS pixels. */
|
|
50
|
+
interface BoundingBox {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
}
|
|
56
|
+
/** A node in the extracted DOM tree. */
|
|
57
|
+
interface DOMNode {
|
|
58
|
+
/** Tag name (lower-cased) or "#text" for text nodes. */
|
|
59
|
+
tag: string;
|
|
60
|
+
/** Element attributes. */
|
|
61
|
+
attrs: Record<string, string>;
|
|
62
|
+
/** Inner text content (for text/leaf nodes). */
|
|
63
|
+
text?: string;
|
|
64
|
+
/** Child nodes. */
|
|
65
|
+
children: DOMNode[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Viewport configuration controlling the SVG viewBox / raster dimensions.
|
|
69
|
+
*/
|
|
70
|
+
interface ViewportOptions {
|
|
71
|
+
width: number;
|
|
72
|
+
height: number;
|
|
73
|
+
}
|
|
74
|
+
/** Available container layout presets. */
|
|
75
|
+
type ContainerType = "centered" | "flex-row" | "flex-col" | "none";
|
|
76
|
+
/**
|
|
77
|
+
* Wrapper container options applied around the rendered component.
|
|
78
|
+
*/
|
|
79
|
+
interface ContainerOptions {
|
|
80
|
+
type: ContainerType;
|
|
81
|
+
/** Padding in pixels (applied to all sides). */
|
|
82
|
+
padding: number;
|
|
83
|
+
/** Background colour (CSS colour string). */
|
|
84
|
+
background?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Controls what is captured in the SatoriRenderer RenderResult.
|
|
88
|
+
*/
|
|
89
|
+
interface CaptureOptions {
|
|
90
|
+
/** Whether to capture a PNG screenshot. Default: true. */
|
|
91
|
+
screenshot: boolean;
|
|
92
|
+
/** Whether to extract computed styles. Default: true. */
|
|
93
|
+
styles: boolean;
|
|
94
|
+
/** Whether to record render timing. Default: true. */
|
|
95
|
+
timing: boolean;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Environment context for the Satori render.
|
|
99
|
+
*/
|
|
100
|
+
interface EnvironmentOptions {
|
|
101
|
+
/** Override viewport dimensions. */
|
|
102
|
+
viewport?: ViewportOptions;
|
|
103
|
+
/** Active theme name (passed to mock ThemeContext). */
|
|
104
|
+
theme?: string;
|
|
105
|
+
/** Locale string (e.g. "en-US"). */
|
|
106
|
+
locale?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Full set of options for a SatoriRenderer render call.
|
|
110
|
+
*/
|
|
111
|
+
interface SatoriRenderOptions {
|
|
112
|
+
viewport?: ViewportOptions;
|
|
113
|
+
container?: Partial<ContainerOptions>;
|
|
114
|
+
capture?: Partial<CaptureOptions>;
|
|
115
|
+
environment?: EnvironmentOptions;
|
|
116
|
+
}
|
|
117
|
+
/** A loaded font entry suitable for passing to Satori. */
|
|
118
|
+
interface FontEntry {
|
|
119
|
+
name: string;
|
|
120
|
+
data: ArrayBuffer;
|
|
121
|
+
weight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
122
|
+
style: "normal" | "italic";
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Construction-time configuration for SatoriRenderer.
|
|
126
|
+
*/
|
|
127
|
+
interface RendererConfig {
|
|
128
|
+
/**
|
|
129
|
+
* Path to a TTF/OTF/WOFF font file (NOT woff2 — opentype.js limitation).
|
|
130
|
+
* If omitted, bundled Inter woff is used via @fontsource/inter.
|
|
131
|
+
*/
|
|
132
|
+
fontPath?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Font family name to advertise. Defaults to "Inter".
|
|
135
|
+
*/
|
|
136
|
+
fontFamily?: string;
|
|
137
|
+
/** Default viewport. */
|
|
138
|
+
defaultViewport?: ViewportOptions;
|
|
139
|
+
}
|
|
140
|
+
/** Per-render options controlling optional BrowserPool capture steps. */
|
|
141
|
+
interface RenderOptions {
|
|
142
|
+
/** Capture and return a DOM tree snapshot. Default: false. */
|
|
143
|
+
captureDom?: boolean;
|
|
144
|
+
/** Capture computed styles for the root element. Default: true. */
|
|
145
|
+
captureStyles?: boolean;
|
|
146
|
+
/** Capture browser console output. Default: false. */
|
|
147
|
+
captureConsole?: boolean;
|
|
148
|
+
/** Capture basic accessibility role/name. Default: false. */
|
|
149
|
+
captureA11y?: boolean;
|
|
150
|
+
/** Viewport width for this render. Defaults to pool-level `viewportWidth`. */
|
|
151
|
+
viewportWidth?: number;
|
|
152
|
+
/** Viewport height for this render. Defaults to pool-level `viewportHeight`. */
|
|
153
|
+
viewportHeight?: number;
|
|
154
|
+
/** Timeout in milliseconds to wait for `window.__renderReady`. Default: 10_000. */
|
|
155
|
+
timeoutMs?: number;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Named pool size presets.
|
|
159
|
+
*
|
|
160
|
+
* | Preset | browsers | pagesPerBrowser | max concurrency |
|
|
161
|
+
* |--------------|----------|-----------------|-----------------
|
|
162
|
+
* | local | 1 | 5 | 5 |
|
|
163
|
+
* | ci-standard | 3 | 15 | 45 |
|
|
164
|
+
* | ci-large | 6 | 20 | 120 |
|
|
165
|
+
*/
|
|
166
|
+
type PoolPreset = "local" | "ci-standard" | "ci-large";
|
|
167
|
+
/** Fine-grained pool sizing configuration. */
|
|
168
|
+
interface PoolSizeConfig {
|
|
169
|
+
/** Number of browser instances to launch. */
|
|
170
|
+
browsers: number;
|
|
171
|
+
/** Number of page contexts per browser. */
|
|
172
|
+
pagesPerBrowser: number;
|
|
173
|
+
}
|
|
174
|
+
/** Full configuration for a `BrowserPool`. */
|
|
175
|
+
interface BrowserPoolConfig {
|
|
176
|
+
/**
|
|
177
|
+
* Named size preset. Mutually exclusive with `size`.
|
|
178
|
+
* When both are omitted, defaults to `"local"`.
|
|
179
|
+
*/
|
|
180
|
+
preset?: PoolPreset;
|
|
181
|
+
/**
|
|
182
|
+
* Custom size configuration. Overrides `preset` when provided.
|
|
183
|
+
*/
|
|
184
|
+
size?: PoolSizeConfig;
|
|
185
|
+
/**
|
|
186
|
+
* Viewport width for all pages in the pool.
|
|
187
|
+
* @default 1440
|
|
188
|
+
*/
|
|
189
|
+
viewportWidth?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Viewport height for all pages in the pool.
|
|
192
|
+
* @default 900
|
|
193
|
+
*/
|
|
194
|
+
viewportHeight?: number;
|
|
195
|
+
/**
|
|
196
|
+
* Maximum milliseconds to wait for an available page before
|
|
197
|
+
* `acquire()` rejects.
|
|
198
|
+
* @default 30_000
|
|
199
|
+
*/
|
|
200
|
+
acquireTimeoutMs?: number;
|
|
201
|
+
}
|
|
202
|
+
/** Internal representation of a single page slot in the pool. */
|
|
203
|
+
interface PageSlot {
|
|
204
|
+
/** Playwright page instance. */
|
|
205
|
+
page: playwright.Page;
|
|
206
|
+
/** Whether this slot is currently checked out. */
|
|
207
|
+
inUse: boolean;
|
|
208
|
+
/** Slot index (for debugging). */
|
|
209
|
+
index: number;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* BrowserPool — Playwright-based browser pool for complex component rendering.
|
|
214
|
+
*
|
|
215
|
+
* ## Design
|
|
216
|
+
*
|
|
217
|
+
* The pool manages N browser instances, each owning M page contexts. Pages are
|
|
218
|
+
* pre-loaded ONCE with a skeleton HTML that includes:
|
|
219
|
+
* - A full React provider tree
|
|
220
|
+
* - CSS / font links
|
|
221
|
+
* - A component registry
|
|
222
|
+
*
|
|
223
|
+
* Components are swapped in via `window.__renderComponent(name, props)` — no
|
|
224
|
+
* page navigation between renders. This "inject-don't-navigate" pattern keeps
|
|
225
|
+
* pages warm and avoids expensive browser startup on every render.
|
|
226
|
+
*
|
|
227
|
+
* ## Concurrency
|
|
228
|
+
*
|
|
229
|
+
* `acquire()` checks out a free `PageSlot`. When all slots are busy, callers
|
|
230
|
+
* queue and are resumed FIFO once a slot becomes available.
|
|
231
|
+
* `release(slot)` returns a slot to the pool and wakes the next waiter.
|
|
232
|
+
*
|
|
233
|
+
* ## Shutdown
|
|
234
|
+
*
|
|
235
|
+
* `close()` drains all in-flight renders (waits for in-use slots) then closes
|
|
236
|
+
* every browser gracefully.
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Manages a pool of Playwright browser instances and page contexts for
|
|
241
|
+
* rendering complex React components.
|
|
242
|
+
*/
|
|
243
|
+
declare class BrowserPool {
|
|
244
|
+
private readonly config;
|
|
245
|
+
private readonly sizeConfig;
|
|
246
|
+
private browsers;
|
|
247
|
+
private slots;
|
|
248
|
+
private waiters;
|
|
249
|
+
private closed;
|
|
250
|
+
private initialized;
|
|
251
|
+
constructor(config?: BrowserPoolConfig);
|
|
252
|
+
/**
|
|
253
|
+
* Launch all browser instances and pre-load every page with the skeleton HTML.
|
|
254
|
+
* Must be called before `render()`.
|
|
255
|
+
*/
|
|
256
|
+
init(): Promise<void>;
|
|
257
|
+
/**
|
|
258
|
+
* Acquire a free page slot. Blocks until one is available or
|
|
259
|
+
* `acquireTimeoutMs` is exceeded.
|
|
260
|
+
*/
|
|
261
|
+
acquire(): Promise<PageSlot>;
|
|
262
|
+
/**
|
|
263
|
+
* Return a page slot to the pool. Wakes the next queued waiter, if any.
|
|
264
|
+
*/
|
|
265
|
+
release(slot: PageSlot): void;
|
|
266
|
+
/**
|
|
267
|
+
* Render a component by name with the given props and return a `RenderResult`.
|
|
268
|
+
*
|
|
269
|
+
* The inject-don't-navigate pattern is used:
|
|
270
|
+
* 1. Acquire a warm page slot.
|
|
271
|
+
* 2. Call `window.__renderComponent(name, props)` — no navigation.
|
|
272
|
+
* 3. Wait for `window.__renderReady`.
|
|
273
|
+
* 4. Clip screenshot to the component bounding box.
|
|
274
|
+
* 5. Optionally capture DOM, styles, console output, and a11y info.
|
|
275
|
+
* 6. Release the slot.
|
|
276
|
+
*/
|
|
277
|
+
render(componentName: string, props?: Record<string, unknown>, options?: RenderOptions): Promise<RenderResult>;
|
|
278
|
+
/**
|
|
279
|
+
* Gracefully shut down the pool.
|
|
280
|
+
*
|
|
281
|
+
* Waits for all in-use slots to be released, then closes every browser.
|
|
282
|
+
* Subsequent `acquire()` or `render()` calls will throw.
|
|
283
|
+
*/
|
|
284
|
+
close(): Promise<void>;
|
|
285
|
+
/** Total number of page slots in the pool. */
|
|
286
|
+
get totalSlots(): number;
|
|
287
|
+
/** Number of currently available (free) slots. */
|
|
288
|
+
get freeSlots(): number;
|
|
289
|
+
/** Number of currently in-use slots. */
|
|
290
|
+
get activeSlots(): number;
|
|
291
|
+
/** Number of callers waiting for a free slot. */
|
|
292
|
+
get queueDepth(): number;
|
|
293
|
+
/** Whether the pool has been initialised. */
|
|
294
|
+
get isInitialized(): boolean;
|
|
295
|
+
/** Whether the pool is closed. */
|
|
296
|
+
get isClosed(): boolean;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Composition Contexts — built-in context types for use as RenderMatrix axes.
|
|
301
|
+
*
|
|
302
|
+
* Each context describes a layout environment in which a component is rendered.
|
|
303
|
+
* Pass an array of `CompositionContext` values as a matrix axis to test how a
|
|
304
|
+
* component behaves across different parent layout contexts.
|
|
305
|
+
*/
|
|
306
|
+
/**
|
|
307
|
+
* All built-in composition context identifiers.
|
|
308
|
+
*
|
|
309
|
+
* | ID | Description |
|
|
310
|
+
* |-----------------|------------------------------------------------------------|
|
|
311
|
+
* | centered | Component centered inside the viewport |
|
|
312
|
+
* | flex-row | Component inside a flex row with sibling placeholders |
|
|
313
|
+
* | flex-col | Component inside a flex column |
|
|
314
|
+
* | grid | Component inside a CSS grid cell |
|
|
315
|
+
* | sidebar | Narrow sidebar layout (240 px wide) |
|
|
316
|
+
* | scroll | Component inside a scrollable container |
|
|
317
|
+
* | full-width | Component stretches to full viewport width |
|
|
318
|
+
* | constrained | Component inside a max-width centered container |
|
|
319
|
+
* | rtl | Right-to-left text direction (dir="rtl") |
|
|
320
|
+
* | nested-flex | Deeply nested flex containers (3 levels) |
|
|
321
|
+
*/
|
|
322
|
+
type CompositionContextId = "centered" | "flex-row" | "flex-col" | "grid" | "sidebar" | "scroll" | "full-width" | "constrained" | "rtl" | "nested-flex";
|
|
323
|
+
/**
|
|
324
|
+
* Describes a composition context: its ID, human-readable label,
|
|
325
|
+
* and the CSS properties to apply to the parent wrapper element.
|
|
326
|
+
*/
|
|
327
|
+
interface CompositionContext {
|
|
328
|
+
/** Stable identifier used as an axis value in RenderMatrix. */
|
|
329
|
+
id: CompositionContextId;
|
|
330
|
+
/** Short human-readable label (used as axis label in sprite sheets). */
|
|
331
|
+
label: string;
|
|
332
|
+
/** CSS properties applied to the wrapping container. */
|
|
333
|
+
containerStyle: Record<string, string>;
|
|
334
|
+
/** Optional HTML attributes applied to the wrapping container. */
|
|
335
|
+
containerAttrs?: Record<string, string>;
|
|
336
|
+
/** Human-readable description of what this context tests. */
|
|
337
|
+
description: string;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* All ten built-in composition contexts.
|
|
341
|
+
*/
|
|
342
|
+
declare const COMPOSITION_CONTEXTS: Record<CompositionContextId, CompositionContext>;
|
|
343
|
+
/** All ten built-in contexts as an ordered array. */
|
|
344
|
+
declare const ALL_CONTEXTS: CompositionContext[];
|
|
345
|
+
/** All context IDs. */
|
|
346
|
+
declare const ALL_CONTEXT_IDS: CompositionContextId[];
|
|
347
|
+
/**
|
|
348
|
+
* Retrieve a context descriptor by ID.
|
|
349
|
+
*
|
|
350
|
+
* @throws if the ID is not recognised.
|
|
351
|
+
*/
|
|
352
|
+
declare function getContext(id: CompositionContextId): CompositionContext;
|
|
353
|
+
/**
|
|
354
|
+
* Retrieve multiple contexts by ID.
|
|
355
|
+
*/
|
|
356
|
+
declare function getContexts(ids: CompositionContextId[]): CompositionContext[];
|
|
357
|
+
/**
|
|
358
|
+
* Returns a `MatrixAxis`-compatible object for use directly in `RenderMatrix`.
|
|
359
|
+
*
|
|
360
|
+
* ```ts
|
|
361
|
+
* const matrix = new RenderMatrix(renderer, [
|
|
362
|
+
* contextAxis(["centered", "flex-row", "rtl"]),
|
|
363
|
+
* { name: "variant", values: ["primary", "secondary"] },
|
|
364
|
+
* ]);
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
declare function contextAxis(ids?: CompositionContextId[]): {
|
|
368
|
+
name: string;
|
|
369
|
+
values: CompositionContext[];
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @agent-scope/render — Structured error handling for crashed renders.
|
|
374
|
+
*
|
|
375
|
+
* When a component crashes during render, this module captures rich
|
|
376
|
+
* diagnostic context instead of letting the error propagate and crash
|
|
377
|
+
* the entire batch.
|
|
378
|
+
*
|
|
379
|
+
* Usage:
|
|
380
|
+
* import { safeRender, RenderError } from "@agent-scope/render";
|
|
381
|
+
*
|
|
382
|
+
* const outcome = await safeRender(() => renderer.renderCell(props), {
|
|
383
|
+
* props,
|
|
384
|
+
* sourceLocation: { file: "Button.tsx", line: 12, column: 0 },
|
|
385
|
+
* });
|
|
386
|
+
*
|
|
387
|
+
* if (outcome.crashed) {
|
|
388
|
+
* console.error(outcome.error.message);
|
|
389
|
+
* console.error("Hints:", outcome.error.heuristicFlags);
|
|
390
|
+
* } else {
|
|
391
|
+
* console.log("Screenshot size:", outcome.result.screenshot.length);
|
|
392
|
+
* }
|
|
393
|
+
*/
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Automated diagnosis hints emitted when a render crashes.
|
|
397
|
+
*
|
|
398
|
+
* Each flag is a short SCREAMING_SNAKE_CASE identifier that encodes a
|
|
399
|
+
* likely root cause. Callers can use these to surface actionable messages
|
|
400
|
+
* to the user without needing to parse raw error messages.
|
|
401
|
+
*/
|
|
402
|
+
type HeuristicFlag = "MISSING_PROVIDER" | "UNDEFINED_PROP" | "TYPE_MISMATCH" | "NETWORK_REQUIRED" | "ASYNC_NOT_SUSPENDED" | "HOOK_CALL_VIOLATION" | "ELEMENT_TYPE_INVALID" | "HYDRATION_MISMATCH" | "CIRCULAR_DEPENDENCY" | "UNKNOWN_ERROR";
|
|
403
|
+
/**
|
|
404
|
+
* The file/line/column origin of a component as recorded in the manifest.
|
|
405
|
+
*/
|
|
406
|
+
interface SourceLocation {
|
|
407
|
+
file: string;
|
|
408
|
+
line: number;
|
|
409
|
+
column: number;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* All structured fields carried by a `RenderError`.
|
|
413
|
+
* Consumers can access these directly on the error instance.
|
|
414
|
+
*/
|
|
415
|
+
interface RenderErrorFields {
|
|
416
|
+
/** The React component stack trace (if available). */
|
|
417
|
+
componentStack: string;
|
|
418
|
+
/** Source location from the manifest. */
|
|
419
|
+
sourceLocation: SourceLocation;
|
|
420
|
+
/** The prop values that were passed to the component when it crashed. */
|
|
421
|
+
propsAtCrash: Record<string, unknown>;
|
|
422
|
+
/** The error message (also available via `error.message`). */
|
|
423
|
+
errorMessage: string;
|
|
424
|
+
/** The error class name (e.g. "TypeError", "ReferenceError"). */
|
|
425
|
+
errorType: string;
|
|
426
|
+
/** Automated diagnosis hints. */
|
|
427
|
+
heuristicFlags: HeuristicFlag[];
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Error thrown (or captured) when a component crashes during render.
|
|
431
|
+
*
|
|
432
|
+
* Extends the native `Error` class so it can be used with standard
|
|
433
|
+
* `instanceof` checks and `catch` clauses, while also carrying rich
|
|
434
|
+
* structured diagnostics.
|
|
435
|
+
*/
|
|
436
|
+
declare class RenderError extends Error implements RenderErrorFields {
|
|
437
|
+
readonly componentStack: string;
|
|
438
|
+
readonly sourceLocation: SourceLocation;
|
|
439
|
+
readonly propsAtCrash: Record<string, unknown>;
|
|
440
|
+
readonly errorMessage: string;
|
|
441
|
+
readonly errorType: string;
|
|
442
|
+
readonly heuristicFlags: HeuristicFlag[];
|
|
443
|
+
constructor(fields: RenderErrorFields);
|
|
444
|
+
/**
|
|
445
|
+
* Construct a `RenderError` from an arbitrary caught value.
|
|
446
|
+
*
|
|
447
|
+
* Extracts `componentStack` from React error boundaries when present,
|
|
448
|
+
* and runs heuristic analysis on the error message.
|
|
449
|
+
*/
|
|
450
|
+
static from(caught: unknown, context?: {
|
|
451
|
+
props?: Record<string, unknown>;
|
|
452
|
+
sourceLocation?: SourceLocation;
|
|
453
|
+
}): RenderError;
|
|
454
|
+
/** Serialise to a plain object (useful for JSON output). */
|
|
455
|
+
toJSON(): RenderErrorFields & {
|
|
456
|
+
name: string;
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Analyse an error message and component stack to produce a list of
|
|
461
|
+
* `HeuristicFlag` values that hint at likely root causes.
|
|
462
|
+
*
|
|
463
|
+
* Exported so that callers can run the analysis independently (e.g. in
|
|
464
|
+
* tests or custom error reporters).
|
|
465
|
+
*/
|
|
466
|
+
declare function detectHeuristicFlags(errorMessage: string, componentStack: string): HeuristicFlag[];
|
|
467
|
+
/**
|
|
468
|
+
* A successful render outcome.
|
|
469
|
+
*/
|
|
470
|
+
interface SuccessRenderResult {
|
|
471
|
+
crashed: false;
|
|
472
|
+
result: RenderResult;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* A crashed render outcome. The `error` carries full diagnostic context.
|
|
476
|
+
*/
|
|
477
|
+
interface CrashedRenderResult {
|
|
478
|
+
crashed: true;
|
|
479
|
+
error: RenderError;
|
|
480
|
+
renderTimeMs: number;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* The result of a `safeRender()` call: either success or a structured
|
|
484
|
+
* crash record.
|
|
485
|
+
*/
|
|
486
|
+
type RenderOutcome = SuccessRenderResult | CrashedRenderResult;
|
|
487
|
+
/**
|
|
488
|
+
* Wraps a render function so that any thrown error is captured as a
|
|
489
|
+
* structured `CrashedRenderResult` instead of propagating.
|
|
490
|
+
*
|
|
491
|
+
* @param renderFn — async function that produces a `RenderResult`.
|
|
492
|
+
* @param context — optional metadata to attach to any crash record.
|
|
493
|
+
*/
|
|
494
|
+
declare function safeRender(renderFn: () => Promise<RenderResult>, context?: {
|
|
495
|
+
props?: Record<string, unknown>;
|
|
496
|
+
sourceLocation?: SourceLocation;
|
|
497
|
+
}): Promise<RenderOutcome>;
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Font loading and caching for SatoriRenderer.
|
|
501
|
+
*
|
|
502
|
+
* Satori requires font data as ArrayBuffer and uses opentype.js internally,
|
|
503
|
+
* which supports TTF/OTF/WOFF but NOT WOFF2.
|
|
504
|
+
*
|
|
505
|
+
* This module:
|
|
506
|
+
* - Loads a font from disk once and caches it in-process.
|
|
507
|
+
* - Returns Satori-compatible FontEntry arrays.
|
|
508
|
+
* - Falls back to the bundled Inter woff font (@fontsource/inter) when no
|
|
509
|
+
* explicit path is provided.
|
|
510
|
+
*/
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Load font data from the given path and return Satori-compatible entries.
|
|
514
|
+
* Results are cached by resolved path for the process lifetime.
|
|
515
|
+
*
|
|
516
|
+
* @param fontPath - Path to a TTF/OTF/WOFF font file (NOT woff2 — opentype.js
|
|
517
|
+
* doesn't support woff2). Pass `undefined` to use the bundled
|
|
518
|
+
* Inter woff font, or empty array if unavailable.
|
|
519
|
+
* @param fontFamily - Family name to advertise. Defaults to "Inter".
|
|
520
|
+
*/
|
|
521
|
+
declare function loadFont(fontPath: string | undefined, fontFamily?: string): Promise<FontEntry[]>;
|
|
522
|
+
/**
|
|
523
|
+
* Clear the font cache. Useful in tests to ensure isolation.
|
|
524
|
+
*/
|
|
525
|
+
declare function clearFontCache(): void;
|
|
526
|
+
/**
|
|
527
|
+
* Returns the number of distinct font paths currently cached.
|
|
528
|
+
*/
|
|
529
|
+
declare function fontCacheSize(): number;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* RenderMatrix — Cartesian product renderer for React component prop axes.
|
|
533
|
+
*
|
|
534
|
+
* Generates all combinations of axis values, renders each cell via either
|
|
535
|
+
* SatoriRenderer (simple components) or BrowserPool (complex components),
|
|
536
|
+
* and returns a structured grid of RenderResult objects with aggregate stats.
|
|
537
|
+
*/
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* A single axis in the render matrix.
|
|
541
|
+
* Each axis defines a dimension of the Cartesian product.
|
|
542
|
+
*/
|
|
543
|
+
interface MatrixAxis<T = unknown> {
|
|
544
|
+
/** Human-readable name for this axis (displayed as row/col label). */
|
|
545
|
+
name: string;
|
|
546
|
+
/** The values along this axis. */
|
|
547
|
+
values: T[];
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Unified renderer interface that both SatoriRenderer and BrowserPool
|
|
551
|
+
* adapters implement. Consumers supply a `MatrixRenderer` to `RenderMatrix`.
|
|
552
|
+
*/
|
|
553
|
+
interface MatrixRenderer {
|
|
554
|
+
/**
|
|
555
|
+
* Render a single cell given the merged props for that cell.
|
|
556
|
+
*
|
|
557
|
+
* @param props - The combined prop snapshot for this matrix cell.
|
|
558
|
+
* Keys are axis names; values are the axis value for this cell.
|
|
559
|
+
* @param complexityClass - Routing hint (passed through from the descriptor).
|
|
560
|
+
* @returns Resolved RenderResult.
|
|
561
|
+
*/
|
|
562
|
+
renderCell(props: Record<string, unknown>, complexityClass: ComplexityClass): Promise<RenderResult>;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* A single cell in the rendered matrix grid.
|
|
566
|
+
*/
|
|
567
|
+
interface MatrixCell {
|
|
568
|
+
/** The axis values that produced this cell (axis name → value). */
|
|
569
|
+
props: Record<string, unknown>;
|
|
570
|
+
/** The render result for this cell. */
|
|
571
|
+
result: RenderResult;
|
|
572
|
+
/** Flat index in the row-major grid. */
|
|
573
|
+
index: number;
|
|
574
|
+
/** Per-axis indices (parallel to axes array). */
|
|
575
|
+
axisIndices: number[];
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Aggregate statistics over all cells in the matrix.
|
|
579
|
+
*/
|
|
580
|
+
interface MatrixStats {
|
|
581
|
+
/** Total number of cells rendered. */
|
|
582
|
+
totalCells: number;
|
|
583
|
+
/** Sum of all cell renderTimeMs values. */
|
|
584
|
+
totalRenderTimeMs: number;
|
|
585
|
+
/** Average renderTimeMs across all cells. */
|
|
586
|
+
avgRenderTimeMs: number;
|
|
587
|
+
/** Fastest individual cell render time. */
|
|
588
|
+
minRenderTimeMs: number;
|
|
589
|
+
/** Slowest individual cell render time. */
|
|
590
|
+
maxRenderTimeMs: number;
|
|
591
|
+
/** Total wall-clock time for the whole matrix render (ms). */
|
|
592
|
+
wallClockTimeMs: number;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* The full result of a matrix render.
|
|
596
|
+
*/
|
|
597
|
+
interface MatrixResult {
|
|
598
|
+
/** Flat list of all rendered cells (row-major order). */
|
|
599
|
+
cells: MatrixCell[];
|
|
600
|
+
/** The axes used to generate this matrix. */
|
|
601
|
+
axes: MatrixAxis[];
|
|
602
|
+
/**
|
|
603
|
+
* 2-D axis label grid: `axisLabels[axisIndex][valueIndex]` → label string.
|
|
604
|
+
* For multi-value objects, we use JSON.stringify as a fallback label.
|
|
605
|
+
*/
|
|
606
|
+
axisLabels: string[][];
|
|
607
|
+
/** Aggregate render statistics. */
|
|
608
|
+
stats: MatrixStats;
|
|
609
|
+
/** Number of rows in the conceptual grid (last axis cardinality). */
|
|
610
|
+
rows: number;
|
|
611
|
+
/** Number of columns in the conceptual grid (second-to-last axis cardinality, or 1). */
|
|
612
|
+
cols: number;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Generates the Cartesian product of an array of arrays.
|
|
616
|
+
*
|
|
617
|
+
* cartesianProduct([[1,2],[3,4]]) → [[1,3],[1,4],[2,3],[2,4]]
|
|
618
|
+
*/
|
|
619
|
+
declare function cartesianProduct<T>(axes: T[][]): T[][];
|
|
620
|
+
/**
|
|
621
|
+
* Produce a human-readable label for an axis value.
|
|
622
|
+
* Primitives are stringified directly; objects/arrays use JSON.stringify.
|
|
623
|
+
*/
|
|
624
|
+
declare function labelForValue(value: unknown): string;
|
|
625
|
+
/**
|
|
626
|
+
* Generates and renders a Cartesian product of prop axis values.
|
|
627
|
+
*
|
|
628
|
+
* Usage:
|
|
629
|
+
* ```ts
|
|
630
|
+
* const matrix = new RenderMatrix(renderer, [
|
|
631
|
+
* { name: "variant", values: ["primary", "secondary"] },
|
|
632
|
+
* { name: "size", values: ["sm", "md", "lg"] },
|
|
633
|
+
* ], { complexityClass: "simple" });
|
|
634
|
+
*
|
|
635
|
+
* const result = await matrix.render();
|
|
636
|
+
* // result.cells has 6 entries (2×3)
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
declare class RenderMatrix {
|
|
640
|
+
private readonly renderer;
|
|
641
|
+
private readonly axes;
|
|
642
|
+
private readonly complexityClass;
|
|
643
|
+
/** Maximum number of cells to render in parallel. @default 8 */
|
|
644
|
+
private readonly concurrency;
|
|
645
|
+
constructor(renderer: MatrixRenderer, axes: MatrixAxis[], options?: {
|
|
646
|
+
complexityClass?: ComplexityClass;
|
|
647
|
+
/** Max parallel renders. Default 8. */
|
|
648
|
+
concurrency?: number;
|
|
649
|
+
});
|
|
650
|
+
/** Total number of cells (product of all axis cardinalities). */
|
|
651
|
+
get cellCount(): number;
|
|
652
|
+
/** Axis labels indexed [axisIndex][valueIndex]. */
|
|
653
|
+
get axisLabels(): string[][];
|
|
654
|
+
/**
|
|
655
|
+
* Render all cells of the matrix.
|
|
656
|
+
*
|
|
657
|
+
* Cells are dispatched with bounded parallelism (up to `concurrency` at once)
|
|
658
|
+
* and returned in row-major order (first axis iterates slowest).
|
|
659
|
+
*/
|
|
660
|
+
render(): Promise<MatrixResult>;
|
|
661
|
+
private _renderWithConcurrency;
|
|
662
|
+
private _computeStats;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Mock provider helpers for SatoriRenderer.
|
|
667
|
+
*
|
|
668
|
+
* Satori renders pure React element trees to SVG — it does NOT execute hooks
|
|
669
|
+
* or context providers at runtime. The functions here produce wrapper JSX
|
|
670
|
+
* elements that supply minimal mock context values so that components that
|
|
671
|
+
* read context don't throw during the shallow JSX-to-SVG pass.
|
|
672
|
+
*
|
|
673
|
+
* Because Satori only cares about the *rendered JSX shape* (not hook side
|
|
674
|
+
* effects), we can safely supply stub contexts.
|
|
675
|
+
*/
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Wrap a React element with mock providers for each requested context name.
|
|
679
|
+
*
|
|
680
|
+
* Unknown context names get a generic empty-object provider created on the
|
|
681
|
+
* fly (safe, avoids crashes for components that only call `useContext` to
|
|
682
|
+
* check if a value is defined).
|
|
683
|
+
*/
|
|
684
|
+
declare function wrapWithProviders(element: React.ReactElement, requiredContexts: string[], options?: {
|
|
685
|
+
theme?: string;
|
|
686
|
+
locale?: string;
|
|
687
|
+
}): React.ReactElement;
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* SatoriRenderer — pure Node.js render path for simple (flexbox-only) components.
|
|
691
|
+
*
|
|
692
|
+
* Pipeline:
|
|
693
|
+
* React element → Satori SVG → @resvg/resvg-js PNG
|
|
694
|
+
*
|
|
695
|
+
* Only handles components with `complexityClass: "simple"` as classified by
|
|
696
|
+
* @agent-scope/manifest. Complex components (CSS grid, absolute positioning,
|
|
697
|
+
* animations) must be rendered via the Browser Pool path.
|
|
698
|
+
*
|
|
699
|
+
* Target performance: ~8 ms per render at 375×812 (mobile viewport).
|
|
700
|
+
*/
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Satori-based renderer for simple (flexbox-only) React components.
|
|
704
|
+
*
|
|
705
|
+
* Usage:
|
|
706
|
+
* ```ts
|
|
707
|
+
* const renderer = new SatoriRenderer();
|
|
708
|
+
* const result = await renderer.render(
|
|
709
|
+
* <Button variant="primary">Click me</Button>,
|
|
710
|
+
* { viewport: { width: 375, height: 200 } },
|
|
711
|
+
* );
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
declare class SatoriRenderer {
|
|
715
|
+
private readonly config;
|
|
716
|
+
private fontsPromise;
|
|
717
|
+
constructor(config?: RendererConfig);
|
|
718
|
+
/**
|
|
719
|
+
* Pre-load and cache the configured font. Calling this before `render()`
|
|
720
|
+
* ensures the first render isn't slowed by font I/O.
|
|
721
|
+
*/
|
|
722
|
+
preloadFont(): Promise<void>;
|
|
723
|
+
private _getFonts;
|
|
724
|
+
/**
|
|
725
|
+
* Render a React element tree to PNG via Satori (SVG) → resvg-js (PNG).
|
|
726
|
+
*
|
|
727
|
+
* @param element - The React element to render (pre-built, not a component class).
|
|
728
|
+
* @param options - Viewport, container, capture, and environment overrides.
|
|
729
|
+
* @param descriptor - Optional ComponentDescriptor for provider wrapping.
|
|
730
|
+
* When provided, `requiredContexts` are used to inject
|
|
731
|
+
* mock providers around the element.
|
|
732
|
+
*/
|
|
733
|
+
render(element: React.ReactElement, options?: SatoriRenderOptions, descriptor?: Pick<ComponentDescriptor, "requiredContexts">): Promise<RenderResult>;
|
|
734
|
+
/**
|
|
735
|
+
* Render at a specific viewport size. Shorthand for `render(el, { viewport })`.
|
|
736
|
+
*/
|
|
737
|
+
renderAt(element: React.ReactElement, width: number, height: number, descriptor?: Pick<ComponentDescriptor, "requiredContexts">): Promise<RenderResult>;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* SpriteSheetGenerator — composites a MatrixResult into a single PNG sprite sheet.
|
|
742
|
+
*
|
|
743
|
+
* Layout:
|
|
744
|
+
* - Rows correspond to the last matrix axis values.
|
|
745
|
+
* - Columns correspond to all remaining axis combinations.
|
|
746
|
+
* - Axis labels are rendered on the top (column labels) and left (row labels) edges.
|
|
747
|
+
* - Cell borders and padding separate each cell visually.
|
|
748
|
+
*
|
|
749
|
+
* Returns:
|
|
750
|
+
* - A single PNG Buffer containing the full composite image.
|
|
751
|
+
* - A `CellCoordinateMap` for programmatic access to individual cell positions.
|
|
752
|
+
*/
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* The pixel bounding box of a single cell within the sprite sheet.
|
|
756
|
+
*/
|
|
757
|
+
interface CellBounds {
|
|
758
|
+
/** Left edge in pixels (from sprite sheet origin). */
|
|
759
|
+
x: number;
|
|
760
|
+
/** Top edge in pixels (from sprite sheet origin). */
|
|
761
|
+
y: number;
|
|
762
|
+
/** Cell width in pixels (content only, excluding padding). */
|
|
763
|
+
width: number;
|
|
764
|
+
/** Cell height in pixels (content only, excluding padding). */
|
|
765
|
+
height: number;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Maps each cell's flat index to its pixel position in the sprite sheet.
|
|
769
|
+
* Access via `coordinates[cellIndex]`.
|
|
770
|
+
*/
|
|
771
|
+
type CellCoordinateMap = CellBounds[];
|
|
772
|
+
/**
|
|
773
|
+
* The output of `SpriteSheetGenerator.generate()`.
|
|
774
|
+
*/
|
|
775
|
+
interface SpriteSheetResult {
|
|
776
|
+
/** Full composite PNG as a Buffer. */
|
|
777
|
+
png: Buffer;
|
|
778
|
+
/** Per-cell bounding boxes within the composite image. */
|
|
779
|
+
coordinates: CellCoordinateMap;
|
|
780
|
+
/** Total sprite sheet width in pixels. */
|
|
781
|
+
width: number;
|
|
782
|
+
/** Total sprite sheet height in pixels. */
|
|
783
|
+
height: number;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Configuration for `SpriteSheetGenerator`.
|
|
787
|
+
*/
|
|
788
|
+
interface SpriteSheetOptions {
|
|
789
|
+
/** Padding in pixels around each cell. @default 8 */
|
|
790
|
+
cellPadding?: number;
|
|
791
|
+
/** Border thickness in pixels between cells. @default 1 */
|
|
792
|
+
borderWidth?: number;
|
|
793
|
+
/** Background colour as a CSS hex string. @default "#f5f5f5" */
|
|
794
|
+
background?: string;
|
|
795
|
+
/** Border colour as a CSS hex string. @default "#cccccc" */
|
|
796
|
+
borderColor?: string;
|
|
797
|
+
/** Height in pixels reserved for column axis labels at the top. @default 32 */
|
|
798
|
+
labelHeight?: number;
|
|
799
|
+
/** Width in pixels reserved for row axis labels on the left. @default 80 */
|
|
800
|
+
labelWidth?: number;
|
|
801
|
+
/** DPI for axis label text rendering. @default 72 */
|
|
802
|
+
labelDpi?: number;
|
|
803
|
+
/** Label text colour (hex). @default "#333333" */
|
|
804
|
+
labelColor?: string;
|
|
805
|
+
/** Label area background colour (hex). @default "#e8e8e8" */
|
|
806
|
+
labelBackground?: string;
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Composites a `MatrixResult` into a single PNG sprite sheet.
|
|
810
|
+
*
|
|
811
|
+
* Usage:
|
|
812
|
+
* ```ts
|
|
813
|
+
* const gen = new SpriteSheetGenerator({ cellPadding: 12 });
|
|
814
|
+
* const { png, coordinates } = await gen.generate(matrixResult);
|
|
815
|
+
* ```
|
|
816
|
+
*/
|
|
817
|
+
declare class SpriteSheetGenerator {
|
|
818
|
+
private readonly opts;
|
|
819
|
+
constructor(options?: SpriteSheetOptions);
|
|
820
|
+
/**
|
|
821
|
+
* Generate a sprite sheet from a `MatrixResult`.
|
|
822
|
+
*
|
|
823
|
+
* Grid layout:
|
|
824
|
+
* - Rows = last axis cardinality
|
|
825
|
+
* - Cols = product of all other axis cardinalities (or 1 if single axis)
|
|
826
|
+
*
|
|
827
|
+
* @param matrixResult - The result of `RenderMatrix.render()`.
|
|
828
|
+
*/
|
|
829
|
+
generate(matrixResult: MatrixResult): Promise<SpriteSheetResult>;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Content Stress Presets — edge-case prop values for use as RenderMatrix axes.
|
|
834
|
+
*
|
|
835
|
+
* Each preset category provides an array of values (of a specific type) that
|
|
836
|
+
* exercise boundary and edge-case conditions: empty input, overflow text,
|
|
837
|
+
* bidirectional text, numeric extremes, empty/huge lists, broken image URLs, etc.
|
|
838
|
+
*
|
|
839
|
+
* Usage:
|
|
840
|
+
* ```ts
|
|
841
|
+
* import { stressAxis } from "@agent-scope/render";
|
|
842
|
+
*
|
|
843
|
+
* const matrix = new RenderMatrix(renderer, [
|
|
844
|
+
* stressAxis("text.short"),
|
|
845
|
+
* { name: "disabled", values: [false, true] },
|
|
846
|
+
* ]);
|
|
847
|
+
* ```
|
|
848
|
+
*/
|
|
849
|
+
/**
|
|
850
|
+
* All built-in stress preset categories.
|
|
851
|
+
*
|
|
852
|
+
* | ID | Description |
|
|
853
|
+
* |-----------------|----------------------------------------------------------|
|
|
854
|
+
* | text.short | Empty string, single char, short word |
|
|
855
|
+
* | text.long | 200+ character strings, repeated words, lorem ipsum |
|
|
856
|
+
* | text.unicode | CJK ideographs, diacritics, emoji, zero-width chars |
|
|
857
|
+
* | text.rtl | Arabic and Hebrew strings |
|
|
858
|
+
* | number.edge | 0, -1, NaN, Infinity, -Infinity, 999999, MAX_SAFE_INT |
|
|
859
|
+
* | list.count | Lists with 0, 1, 3, 10, 100, 1000 items |
|
|
860
|
+
* | image.states | null URL, broken URL, 1×1 data URI, very large image URL |
|
|
861
|
+
*/
|
|
862
|
+
type StressCategoryId = "text.short" | "text.long" | "text.unicode" | "text.rtl" | "number.edge" | "list.count" | "image.states";
|
|
863
|
+
/**
|
|
864
|
+
* A named set of stress values for a specific data category.
|
|
865
|
+
*/
|
|
866
|
+
interface StressPreset<T = unknown> {
|
|
867
|
+
/** Stable category identifier. */
|
|
868
|
+
id: StressCategoryId;
|
|
869
|
+
/** Short human-readable label (used as axis name). */
|
|
870
|
+
label: string;
|
|
871
|
+
/** Human-readable description of what this preset exercises. */
|
|
872
|
+
description: string;
|
|
873
|
+
/** The stress values. */
|
|
874
|
+
values: T[];
|
|
875
|
+
/** Labels parallel to `values` for display in sprite sheets. */
|
|
876
|
+
valueLabels: string[];
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Retrieve a stress preset by category ID.
|
|
880
|
+
*
|
|
881
|
+
* @throws if the ID is not recognised.
|
|
882
|
+
*/
|
|
883
|
+
declare function getStressPreset(id: StressCategoryId): StressPreset;
|
|
884
|
+
/**
|
|
885
|
+
* Retrieve multiple stress presets.
|
|
886
|
+
*/
|
|
887
|
+
declare function getStressPresets(ids: StressCategoryId[]): StressPreset[];
|
|
888
|
+
/** All built-in stress presets as an ordered array. */
|
|
889
|
+
declare const ALL_STRESS_PRESETS: StressPreset[];
|
|
890
|
+
/** All stress category IDs. */
|
|
891
|
+
declare const ALL_STRESS_IDS: StressCategoryId[];
|
|
892
|
+
/**
|
|
893
|
+
* Returns a `MatrixAxis`-compatible object for direct use in `RenderMatrix`.
|
|
894
|
+
*
|
|
895
|
+
* ```ts
|
|
896
|
+
* const matrix = new RenderMatrix(renderer, [
|
|
897
|
+
* stressAxis("text.short"),
|
|
898
|
+
* { name: "disabled", values: [false, true] },
|
|
899
|
+
* ]);
|
|
900
|
+
* ```
|
|
901
|
+
*/
|
|
902
|
+
declare function stressAxis(id: StressCategoryId): {
|
|
903
|
+
name: string;
|
|
904
|
+
values: unknown[];
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Inline-style extraction utilities for SatoriRenderer.
|
|
909
|
+
*
|
|
910
|
+
* Satori accepts React elements with inline `style` props. This module walks
|
|
911
|
+
* a React element tree and extracts those styles into the ComputedStyles map
|
|
912
|
+
* that is returned as part of RenderResult.
|
|
913
|
+
*/
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Walk a React element tree and collect all inline `style` objects.
|
|
917
|
+
*
|
|
918
|
+
* The key in the returned map is a dot-delimited path describing the element's
|
|
919
|
+
* position in the tree, e.g. "root", "root.0", "root.0.1".
|
|
920
|
+
*
|
|
921
|
+
* Only elements with a non-empty `style` prop are included.
|
|
922
|
+
*/
|
|
923
|
+
declare function extractInlineStyles(element: React.ReactNode, path?: string): Record<string, Record<string, string>>;
|
|
924
|
+
|
|
925
|
+
export { ALL_CONTEXTS, ALL_CONTEXT_IDS, ALL_STRESS_IDS, ALL_STRESS_PRESETS, type BoundingBox, BrowserPool, type BrowserPoolConfig, COMPOSITION_CONTEXTS, type CaptureOptions, type CellBounds, type CellCoordinateMap, type CompositionContext, type CompositionContextId, type ContainerOptions, type ContainerType, type CrashedRenderResult, type DOMNode, type EnvironmentOptions, type FontEntry, type HeuristicFlag, type MatrixAxis, type MatrixCell, type MatrixRenderer, type MatrixResult, type MatrixStats, type PageSlot, type PoolPreset, type PoolSizeConfig, RenderError, type RenderErrorFields, RenderMatrix, type RenderOptions, type RenderOutcome, type RenderResult, type RendererConfig, type SatoriRenderOptions, SatoriRenderer, type SourceLocation, SpriteSheetGenerator, type SpriteSheetOptions, type SpriteSheetResult, type StressCategoryId, type StressPreset, type SuccessRenderResult, type ViewportOptions, cartesianProduct, clearFontCache, contextAxis, detectHeuristicFlags, extractInlineStyles, fontCacheSize, getContext, getContexts, getStressPreset, getStressPresets, labelForValue, loadFont, safeRender, stressAxis, wrapWithProviders };
|