wasm-html-to-image 0.1.0

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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +326 -0
  3. package/dist/browser-workers.d.ts +12 -0
  4. package/dist/browser-workers.js +26 -0
  5. package/dist/child-workers.d.ts +11 -0
  6. package/dist/child-workers.js +19 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +87 -0
  9. package/dist/core.d.ts +168 -0
  10. package/dist/core.js +824 -0
  11. package/dist/diagnostics.d.ts +93 -0
  12. package/dist/diagnostics.js +28 -0
  13. package/dist/edge-light.d.ts +18 -0
  14. package/dist/edge-light.js +70 -0
  15. package/dist/encode-args.d.ts +10 -0
  16. package/dist/encode-args.js +30 -0
  17. package/dist/html-to-image-single.js +0 -0
  18. package/dist/html-to-image-wasm.js +3 -0
  19. package/dist/html-to-image.js +2 -0
  20. package/dist/html-to-image.wasm +0 -0
  21. package/dist/index.d.ts +14 -0
  22. package/dist/index.js +14 -0
  23. package/dist/input.d.ts +23 -0
  24. package/dist/input.js +90 -0
  25. package/dist/loader.d.ts +132 -0
  26. package/dist/loader.js +199 -0
  27. package/dist/preact.d.ts +10 -0
  28. package/dist/preact.js +13 -0
  29. package/dist/react.d.ts +9 -0
  30. package/dist/react.js +11 -0
  31. package/dist/single.d.ts +27 -0
  32. package/dist/single.js +22 -0
  33. package/dist/tailwind.d.ts +1 -0
  34. package/dist/tailwind.js +6 -0
  35. package/dist/wasm-payload.d.ts +2 -0
  36. package/dist/wasm-payload.js +39 -0
  37. package/dist/web-workers.js +4411 -0
  38. package/dist/worker-actions.d.ts +10 -0
  39. package/dist/worker-actions.js +13 -0
  40. package/dist/worker-lib-loader.d.ts +19 -0
  41. package/dist/worker-lib-loader.js +34 -0
  42. package/dist/workerd.d.ts +18 -0
  43. package/dist/workerd.js +65 -0
  44. package/dist/workers-dummy.d.ts +12 -0
  45. package/dist/workers-dummy.js +6 -0
  46. package/dist/workers-parent.js +602 -0
  47. package/dist/workers.d.ts +86 -0
  48. package/dist/workers.js +163 -0
  49. package/package.json +166 -0
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Playground-parity diagnostics (satoru-compatible shapes).
3
+ *
4
+ * `LogLevel` mirrors `satoru/log-level.ts` verbatim (numeric levels shared
5
+ * with the WASM `set_log_level` binding). `RenderDiagnostics` mirrors
6
+ * satoru's `RenderDiagnostics` so playground-style consumers can switch
7
+ * imports without reshaping reports.
8
+ */
9
+ /** Log severity, shared with the WASM `set_log_level` binding. */
10
+ export declare enum LogLevel {
11
+ None = 0,
12
+ Error = 1,
13
+ Warning = 2,
14
+ Info = 3,
15
+ Debug = 4
16
+ }
17
+ /** Status of a single discovered resource. */
18
+ export interface ResourceDiagnostic {
19
+ type: "font" | "css" | "image";
20
+ url: string;
21
+ name?: string;
22
+ status: "pending" | "loaded" | "failed" | "skipped";
23
+ bytes?: number;
24
+ reason?: string;
25
+ }
26
+ /**
27
+ * Font record (best effort, JS-side only).
28
+ * NOTE: per-glyph C++ diagnostics (`get_font_diagnostics`) have no binding
29
+ * in this build (see `src/cpp/main.cpp`), so entries describe fonts this
30
+ * layer loaded (option preloads, fetched font resources) rather than the
31
+ * renderer's matched faces.
32
+ */
33
+ export interface FontDiagnostic {
34
+ family: string;
35
+ weight?: number;
36
+ style?: "normal" | "italic" | "oblique";
37
+ status: "loaded" | "fallback" | "missing";
38
+ source?: string;
39
+ characters?: string;
40
+ }
41
+ /** A warning/error entry in the diagnostics report. */
42
+ export interface DiagnosticMessage {
43
+ code: string;
44
+ message: string;
45
+ source?: string;
46
+ }
47
+ /** Full render diagnostics report (satoru-compatible). */
48
+ export interface RenderDiagnostics {
49
+ version: 1;
50
+ format: "svg" | "png" | "webp" | "pdf";
51
+ width: number;
52
+ height?: number;
53
+ mediaType: "screen" | "print";
54
+ timings: Record<string, number>;
55
+ resources: ResourceDiagnostic[];
56
+ fonts: FontDiagnostic[];
57
+ warnings: DiagnosticMessage[];
58
+ errors: DiagnosticMessage[];
59
+ }
60
+ /** Machine-readable diagnostic codes (satoru parity). */
61
+ export declare const DIAGNOSTIC_CODES: {
62
+ readonly LIMIT_TIMEOUT: "LIMIT_TIMEOUT";
63
+ readonly LIMIT_RESOURCE_SIZE: "LIMIT_RESOURCE_SIZE";
64
+ readonly LIMIT_TOTAL_SIZE: "LIMIT_TOTAL_SIZE";
65
+ readonly LIMIT_RESOURCE_COUNT: "LIMIT_RESOURCE_COUNT";
66
+ readonly LIMIT_PROTOCOL_BLOCKED: "LIMIT_PROTOCOL_BLOCKED";
67
+ readonly LIMIT_HOST_BLOCKED: "LIMIT_HOST_BLOCKED";
68
+ /** Extension: a resource fetch (or resolveResource hook) failed. */
69
+ readonly RESOURCE_FETCH_FAILED: "RESOURCE_FETCH_FAILED";
70
+ };
71
+ /** Safety/performance limits, enforced in JS around resource resolution. */
72
+ export interface RenderLimits {
73
+ /** Timeout for the whole render in milliseconds. */
74
+ timeoutMs?: number;
75
+ /** Maximum bytes for a single resource. */
76
+ maxResourceBytes?: number;
77
+ /** Maximum total bytes for all resources. */
78
+ maxTotalResourceBytes?: number;
79
+ /** Maximum number of resources to load. */
80
+ maxResourceCount?: number;
81
+ /** Allowed URL protocols (e.g. `["http:", "https:"]`). */
82
+ allowedProtocols?: string[];
83
+ /** Allowed hostnames. */
84
+ allowedHosts?: string[];
85
+ /** Blocked hostnames. */
86
+ blockedHosts?: string[];
87
+ }
88
+ /**
89
+ * Override hook for resource resolution. Receives the absolute (or
90
+ * baseUrl-relative) URL and a fallback that runs the built-in resolution;
91
+ * return bytes to inject, or `null` to skip the resource.
92
+ */
93
+ export type ResolveResourceHook = (url: string, fallback: () => Promise<Uint8Array | null>) => Promise<Uint8Array | null>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Playground-parity diagnostics (satoru-compatible shapes).
3
+ *
4
+ * `LogLevel` mirrors `satoru/log-level.ts` verbatim (numeric levels shared
5
+ * with the WASM `set_log_level` binding). `RenderDiagnostics` mirrors
6
+ * satoru's `RenderDiagnostics` so playground-style consumers can switch
7
+ * imports without reshaping reports.
8
+ */
9
+ /** Log severity, shared with the WASM `set_log_level` binding. */
10
+ export var LogLevel;
11
+ (function (LogLevel) {
12
+ LogLevel[LogLevel["None"] = 0] = "None";
13
+ LogLevel[LogLevel["Error"] = 1] = "Error";
14
+ LogLevel[LogLevel["Warning"] = 2] = "Warning";
15
+ LogLevel[LogLevel["Info"] = 3] = "Info";
16
+ LogLevel[LogLevel["Debug"] = 4] = "Debug";
17
+ })(LogLevel || (LogLevel = {}));
18
+ /** Machine-readable diagnostic codes (satoru parity). */
19
+ export const DIAGNOSTIC_CODES = {
20
+ LIMIT_TIMEOUT: "LIMIT_TIMEOUT",
21
+ LIMIT_RESOURCE_SIZE: "LIMIT_RESOURCE_SIZE",
22
+ LIMIT_TOTAL_SIZE: "LIMIT_TOTAL_SIZE",
23
+ LIMIT_RESOURCE_COUNT: "LIMIT_RESOURCE_COUNT",
24
+ LIMIT_PROTOCOL_BLOCKED: "LIMIT_PROTOCOL_BLOCKED",
25
+ LIMIT_HOST_BLOCKED: "LIMIT_HOST_BLOCKED",
26
+ /** Extension: a resource fetch (or resolveResource hook) failed. */
27
+ RESOURCE_FETCH_FAILED: "RESOURCE_FETCH_FAILED",
28
+ };
@@ -0,0 +1,18 @@
1
+ import { type HtmlToImageModule } from "./loader.js";
2
+ import { type HtmlToImageOptions, type RenderResult } from "./core.js";
3
+ export type { OutputFormat, RenderOptions, HtmlToImageOptions, RenderResult, DiagnosticMessage, FontDiagnostic, RenderDiagnostics, RenderLimits, ResolveResourceHook, ResourceDiagnostic, } from "./core.js";
4
+ export { DIAGNOSTIC_CODES, LogLevel } from "./core.js";
5
+ export type { HtmlToImageModule, EmscriptenModuleArg, LoadOptions, WasmInstancePtr, CreateHtmlToImageModule, } from "./loader.js";
6
+ /**
7
+ * Load (and reuse) the unified module for a pre-compiled `WebAssembly.Module`.
8
+ * @param wasm The compiled WASM module (always required — no bundled default)
9
+ */
10
+ export declare function getDefaultModule(wasm: WebAssembly.Module): Promise<HtmlToImageModule>;
11
+ /**
12
+ * Render HTML — or convert an image — on an edge runtime.
13
+ * Returns RenderResult containing data and metadata.
14
+ */
15
+ export declare function render(options: HtmlToImageOptions & {
16
+ format: "svg";
17
+ }, wasm: WebAssembly.Module): Promise<RenderResult<string>>;
18
+ export declare function render(options: HtmlToImageOptions, wasm: WebAssembly.Module): Promise<RenderResult<Uint8Array | string>>;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Edge-light entry point (Next.js Edge runtime, Vercel edge-light).
3
+ *
4
+ * Same engine as `./workerd.js`, but with NO static `.wasm` import:
5
+ * bundlers outside workerd (notably Next.js edge-server compilation) cannot
6
+ * resolve a bare `import wasm from "../dist/html-to-image.wasm"`, so that
7
+ * line would force consumers to add a dedicated `asset/resource` rule.
8
+ * Here the caller always supplies a pre-compiled `WebAssembly.Module`
9
+ * (e.g. compiled from bytes served over HTTP), and instantiation is
10
+ * overridden via `instantiateWasm` exactly like `./workerd.js`.
11
+ *
12
+ * Runtime separation is done in `package.json` `exports` conditions:
13
+ * - `workerd` (Cloudflare) -> `./workerd.js` (static `.wasm` import)
14
+ * - `edge-light` (Next.js Edge) -> `./edge-light.js` (this file)
15
+ * The two conditions never overlap (verified against Next.js 15
16
+ * `edgeConditionNames` and wrangler/miniflare build conditions), and
17
+ * `edge-light` is listed before any `browser` key so Edge resolution wins.
18
+ *
19
+ * ```ts
20
+ * import { render } from "wasm-html-to-image/workerd"; // edge-light resolves here on Edge
21
+ * const wasm = await WebAssembly.compile(await (await fetch(wasmUrl)).arrayBuffer());
22
+ * const png = await render({ value: "<h1>hi</h1>", width: 800, format: "png" }, wasm);
23
+ * ```
24
+ */
25
+ // @ts-expect-error — dist/html-to-image.js is generated at build time
26
+ import createHtmlToImageModule from "./html-to-image.js";
27
+ import { loadHtmlToImageModule, } from "./loader.js";
28
+ import { htmlToImage, } from "./core.js";
29
+ export { DIAGNOSTIC_CODES, LogLevel } from "./core.js";
30
+ /** Build the Emscripten module args overriding WASM instantiation. */
31
+ function edgeModuleArg(wasm) {
32
+ return {
33
+ instantiateWasm: (imports, successCallback) => {
34
+ WebAssembly.instantiate(wasm, imports)
35
+ .then((instance) => {
36
+ successCallback(instance, wasm);
37
+ })
38
+ .catch((e) => {
39
+ console.error("wasm-html-to-image [edge-light]: Wasm instantiation failed:", e);
40
+ });
41
+ return {}; // Return empty object as emscripten expects
42
+ },
43
+ };
44
+ }
45
+ /** Module instances keyed by WASM binary: a second call with a different
46
+ * `wasm` must not silently reuse the first one. Failed loads are evicted
47
+ * so a later call can retry. */
48
+ const moduleByWasm = new Map();
49
+ /**
50
+ * Load (and reuse) the unified module for a pre-compiled `WebAssembly.Module`.
51
+ * @param wasm The compiled WASM module (always required — no bundled default)
52
+ */
53
+ export function getDefaultModule(wasm) {
54
+ let pending = moduleByWasm.get(wasm);
55
+ if (!pending) {
56
+ pending = loadHtmlToImageModule({
57
+ factory: createHtmlToImageModule,
58
+ moduleArg: edgeModuleArg(wasm),
59
+ });
60
+ moduleByWasm.set(wasm, pending);
61
+ pending.catch(() => {
62
+ if (moduleByWasm.get(wasm) === pending)
63
+ moduleByWasm.delete(wasm);
64
+ });
65
+ }
66
+ return pending;
67
+ }
68
+ export async function render(options, wasm) {
69
+ return htmlToImage(await getDefaultModule(wasm), options);
70
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Encode-argument conversion (moved verbatim from `./core.ts`; behavior
3
+ * unchanged): WASM int enums and render-option object construction.
4
+ */
5
+ import type { HtmlToImageOptions, OutputFormat } from "./core.js";
6
+ /** `RenderFormat` enum values (mirrors `bridge_types.h`). */
7
+ export declare const FORMAT_INT: Record<OutputFormat, number>;
8
+ export declare const FIT_INT: Record<NonNullable<HtmlToImageOptions["fit"]>, number>;
9
+ /** Map `crop`/`fit` to satoru render-option fields (`parse_satoru_options`). */
10
+ export declare function buildSatoruOptions(crop: HtmlToImageOptions["crop"], fit: HtmlToImageOptions["fit"]): Record<string, unknown>;
@@ -0,0 +1,30 @@
1
+ /** `RenderFormat` enum values (mirrors `bridge_types.h`). */
2
+ export const FORMAT_INT = {
3
+ svg: 0,
4
+ png: 1,
5
+ webp: 2,
6
+ pdf: 3,
7
+ jpeg: 4,
8
+ avif: 5,
9
+ raw: 6,
10
+ thumbhash: 7,
11
+ none: -1,
12
+ };
13
+ export const FIT_INT = {
14
+ contain: 0,
15
+ cover: 1,
16
+ fill: 2,
17
+ };
18
+ /** Map `crop`/`fit` to satoru render-option fields (`parse_satoru_options`). */
19
+ export function buildSatoruOptions(crop, fit) {
20
+ const o = {};
21
+ if (crop) {
22
+ o.cropX = crop.x;
23
+ o.cropY = crop.y;
24
+ o.cropWidth = crop.width;
25
+ o.cropHeight = crop.height;
26
+ }
27
+ if (fit)
28
+ o.fitType = FIT_INT[fit];
29
+ return o;
30
+ }
Binary file