@effing/satori 0.10.0 → 0.10.2

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.
@@ -4,9 +4,19 @@ var ELEMENT_MARKER = "__react_element__";
4
4
  function expandElement(node) {
5
5
  if (node == null || typeof node === "boolean") return node;
6
6
  if (typeof node === "string" || typeof node === "number") return node;
7
- if (Array.isArray(node)) return node.map(expandElement);
7
+ if (Array.isArray(node)) {
8
+ return node.flatMap((child) => {
9
+ const result = expandElement(child);
10
+ return Array.isArray(result) ? result : [result];
11
+ });
12
+ }
8
13
  if (!React.isValidElement(node)) return node;
9
14
  const element = node;
15
+ if (element.type === React.Fragment) {
16
+ const children = element.props.children;
17
+ if (children == null) return null;
18
+ return expandElement(children);
19
+ }
10
20
  if (typeof element.type === "function") {
11
21
  const result = element.type(
12
22
  element.props
@@ -33,6 +43,11 @@ function serializeElement(node) {
33
43
  `Cannot serialize function component "${element.type.name || "anonymous"}". Call expandElement first.`
34
44
  );
35
45
  }
46
+ if (typeof element.type !== "string") {
47
+ throw new Error(
48
+ `Cannot serialize element with type "${String(element.type)}". Call expandElement first.`
49
+ );
50
+ }
36
51
  const props = {};
37
52
  for (const [key, value] of Object.entries(
38
53
  element.props
@@ -81,4 +96,4 @@ export {
81
96
  serializeElement,
82
97
  deserializeElement
83
98
  };
84
- //# sourceMappingURL=chunk-H5M6ZFOA.js.map
99
+ //# sourceMappingURL=chunk-SGDNREDY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/serde/index.ts"],"sourcesContent":["import React, { type ReactElement, type ReactNode } from \"react\";\n\nconst ELEMENT_MARKER = \"__react_element__\";\n\ntype SerializedElement = {\n [ELEMENT_MARKER]: true;\n type: string;\n key: string | null;\n props: Record<string, unknown>;\n};\n\n/**\n * Recursively expand all function components in a React element tree\n * until only intrinsic elements (div, svg, path, img, etc.) remain.\n */\nexport function expandElement(node: ReactNode): ReactNode {\n if (node == null || typeof node === \"boolean\") return node;\n if (typeof node === \"string\" || typeof node === \"number\") return node;\n if (Array.isArray(node)) {\n return node.flatMap((child) => {\n const result = expandElement(child);\n return Array.isArray(result) ? result : [result];\n });\n }\n\n if (!React.isValidElement(node)) return node;\n\n const element = node as ReactElement;\n\n if (element.type === React.Fragment) {\n const children = (element.props as Record<string, unknown>)\n .children as ReactNode;\n if (children == null) return null;\n return expandElement(children);\n }\n\n if (typeof element.type === \"function\") {\n const result = (element.type as (props: unknown) => ReactNode)(\n element.props,\n );\n return expandElement(result);\n }\n\n // Intrinsic element — recursively expand children\n const props = Object.assign({}, element.props) as Record<string, unknown>;\n if (props.children != null) {\n props.children = expandElement(props.children as ReactNode);\n }\n return React.createElement(element.type as string, {\n ...props,\n key: element.key,\n });\n}\n\n/**\n * Serialize an expanded React element tree to a structured-clone-safe format.\n * All function components must already be expanded to intrinsic elements.\n */\nexport function serializeElement(node: ReactNode): unknown {\n if (node == null || typeof node === \"boolean\") return node;\n if (typeof node === \"string\" || typeof node === \"number\") return node;\n if (Array.isArray(node)) return node.map(serializeElement);\n\n if (!React.isValidElement(node)) return node;\n\n const element = node as ReactElement;\n\n if (typeof element.type === \"function\") {\n throw new Error(\n `Cannot serialize function component \"${element.type.name || \"anonymous\"}\". ` +\n \"Call expandElement first.\",\n );\n }\n\n if (typeof element.type !== \"string\") {\n throw new Error(\n `Cannot serialize element with type \"${String(element.type)}\". Call expandElement first.`,\n );\n }\n\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n element.props as Record<string, unknown>,\n )) {\n if (key === \"children\") {\n props.children = serializeElement(value as ReactNode);\n } else if (value instanceof Buffer) {\n props[key] = { __buffer__: true, data: Array.from(value) };\n } else {\n props[key] = value;\n }\n }\n\n return {\n [ELEMENT_MARKER]: true,\n type: element.type as string,\n key: element.key,\n props,\n } satisfies SerializedElement;\n}\n\n/**\n * Deserialize a serialized element tree back into React elements.\n */\nexport function deserializeElement(data: unknown): ReactNode {\n if (data == null || typeof data === \"boolean\") return data as ReactNode;\n if (typeof data === \"string\" || typeof data === \"number\") return data;\n if (Array.isArray(data)) return data.map(deserializeElement);\n\n if (typeof data === \"object\" && data !== null && ELEMENT_MARKER in data) {\n const serialized = data as SerializedElement;\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(serialized.props)) {\n if (key === \"children\") {\n props.children = deserializeElement(value);\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n \"__buffer__\" in value\n ) {\n props[key] = Buffer.from((value as unknown as { data: number[] }).data);\n } else {\n props[key] = value;\n }\n }\n return React.createElement(serialized.type, {\n ...props,\n key: serialized.key,\n });\n }\n\n return data as ReactNode;\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  expandElement,
3
3
  serializeElement
4
- } from "../chunk-H5M6ZFOA.js";
4
+ } from "../chunk-SGDNREDY.js";
5
5
 
6
6
  // src/pool/index.ts
7
7
  import os from "os";
@@ -2,7 +2,7 @@ import {
2
2
  deserializeElement,
3
3
  expandElement,
4
4
  serializeElement
5
- } from "../chunk-H5M6ZFOA.js";
5
+ } from "../chunk-SGDNREDY.js";
6
6
  export {
7
7
  deserializeElement,
8
8
  expandElement,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effing/satori",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Render JSX to PNG using Satori with emoji support",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/serde/index.ts"],"sourcesContent":["import React, { type ReactElement, type ReactNode } from \"react\";\n\nconst ELEMENT_MARKER = \"__react_element__\";\n\ntype SerializedElement = {\n [ELEMENT_MARKER]: true;\n type: string;\n key: string | null;\n props: Record<string, unknown>;\n};\n\n/**\n * Recursively expand all function components in a React element tree\n * until only intrinsic elements (div, svg, path, img, etc.) remain.\n */\nexport function expandElement(node: ReactNode): ReactNode {\n if (node == null || typeof node === \"boolean\") return node;\n if (typeof node === \"string\" || typeof node === \"number\") return node;\n if (Array.isArray(node)) return node.map(expandElement);\n\n if (!React.isValidElement(node)) return node;\n\n const element = node as ReactElement;\n\n if (typeof element.type === \"function\") {\n const result = (element.type as (props: unknown) => ReactNode)(\n element.props,\n );\n return expandElement(result);\n }\n\n // Intrinsic element — recursively expand children\n const props = Object.assign({}, element.props) as Record<string, unknown>;\n if (props.children != null) {\n props.children = expandElement(props.children as ReactNode);\n }\n return React.createElement(element.type as string, {\n ...props,\n key: element.key,\n });\n}\n\n/**\n * Serialize an expanded React element tree to a structured-clone-safe format.\n * All function components must already be expanded to intrinsic elements.\n */\nexport function serializeElement(node: ReactNode): unknown {\n if (node == null || typeof node === \"boolean\") return node;\n if (typeof node === \"string\" || typeof node === \"number\") return node;\n if (Array.isArray(node)) return node.map(serializeElement);\n\n if (!React.isValidElement(node)) return node;\n\n const element = node as ReactElement;\n\n if (typeof element.type === \"function\") {\n throw new Error(\n `Cannot serialize function component \"${element.type.name || \"anonymous\"}\". ` +\n \"Call expandElement first.\",\n );\n }\n\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n element.props as Record<string, unknown>,\n )) {\n if (key === \"children\") {\n props.children = serializeElement(value as ReactNode);\n } else if (value instanceof Buffer) {\n props[key] = { __buffer__: true, data: Array.from(value) };\n } else {\n props[key] = value;\n }\n }\n\n return {\n [ELEMENT_MARKER]: true,\n type: element.type as string,\n key: element.key,\n props,\n } satisfies SerializedElement;\n}\n\n/**\n * Deserialize a serialized element tree back into React elements.\n */\nexport function deserializeElement(data: unknown): ReactNode {\n if (data == null || typeof data === \"boolean\") return data as ReactNode;\n if (typeof data === \"string\" || typeof data === \"number\") return data;\n if (Array.isArray(data)) return data.map(deserializeElement);\n\n if (typeof data === \"object\" && data !== null && ELEMENT_MARKER in data) {\n const serialized = data as SerializedElement;\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(serialized.props)) {\n if (key === \"children\") {\n props.children = deserializeElement(value);\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n \"__buffer__\" in value\n ) {\n props[key] = Buffer.from((value as unknown as { data: number[] }).data);\n } else {\n props[key] = value;\n }\n }\n return React.createElement(serialized.type, {\n ...props,\n key: serialized.key,\n });\n }\n\n return data as ReactNode;\n}\n"],"mappings":";AAAA,OAAO,WAAkD;AAEzD,IAAM,iBAAiB;AAahB,SAAS,cAAc,MAA4B;AACxD,MAAI,QAAQ,QAAQ,OAAO,SAAS,UAAW,QAAO;AACtD,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAAU,QAAO;AACjE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,aAAa;AAEtD,MAAI,CAAC,MAAM,eAAe,IAAI,EAAG,QAAO;AAExC,QAAM,UAAU;AAEhB,MAAI,OAAO,QAAQ,SAAS,YAAY;AACtC,UAAM,SAAU,QAAQ;AAAA,MACtB,QAAQ;AAAA,IACV;AACA,WAAO,cAAc,MAAM;AAAA,EAC7B;AAGA,QAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,QAAQ,KAAK;AAC7C,MAAI,MAAM,YAAY,MAAM;AAC1B,UAAM,WAAW,cAAc,MAAM,QAAqB;AAAA,EAC5D;AACA,SAAO,MAAM,cAAc,QAAQ,MAAgB;AAAA,IACjD,GAAG;AAAA,IACH,KAAK,QAAQ;AAAA,EACf,CAAC;AACH;AAMO,SAAS,iBAAiB,MAA0B;AACzD,MAAI,QAAQ,QAAQ,OAAO,SAAS,UAAW,QAAO;AACtD,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAAU,QAAO;AACjE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,gBAAgB;AAEzD,MAAI,CAAC,MAAM,eAAe,IAAI,EAAG,QAAO;AAExC,QAAM,UAAU;AAEhB,MAAI,OAAO,QAAQ,SAAS,YAAY;AACtC,UAAM,IAAI;AAAA,MACR,wCAAwC,QAAQ,KAAK,QAAQ,WAAW;AAAA,IAE1E;AAAA,EACF;AAEA,QAAM,QAAiC,CAAC;AACxC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO;AAAA,IAChC,QAAQ;AAAA,EACV,GAAG;AACD,QAAI,QAAQ,YAAY;AACtB,YAAM,WAAW,iBAAiB,KAAkB;AAAA,IACtD,WAAW,iBAAiB,QAAQ;AAClC,YAAM,GAAG,IAAI,EAAE,YAAY,MAAM,MAAM,MAAM,KAAK,KAAK,EAAE;AAAA,IAC3D,OAAO;AACL,YAAM,GAAG,IAAI;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL,CAAC,cAAc,GAAG;AAAA,IAClB,MAAM,QAAQ;AAAA,IACd,KAAK,QAAQ;AAAA,IACb;AAAA,EACF;AACF;AAKO,SAAS,mBAAmB,MAA0B;AAC3D,MAAI,QAAQ,QAAQ,OAAO,SAAS,UAAW,QAAO;AACtD,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAAU,QAAO;AACjE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,kBAAkB;AAE3D,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,kBAAkB,MAAM;AACvE,UAAM,aAAa;AACnB,UAAM,QAAiC,CAAC;AACxC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,KAAK,GAAG;AAC3D,UAAI,QAAQ,YAAY;AACtB,cAAM,WAAW,mBAAmB,KAAK;AAAA,MAC3C,WACE,OAAO,UAAU,YACjB,UAAU,QACV,gBAAgB,OAChB;AACA,cAAM,GAAG,IAAI,OAAO,KAAM,MAAwC,IAAI;AAAA,MACxE,OAAO;AACL,cAAM,GAAG,IAAI;AAAA,MACf;AAAA,IACF;AACA,WAAO,MAAM,cAAc,WAAW,MAAM;AAAA,MAC1C,GAAG;AAAA,MACH,KAAK,WAAW;AAAA,IAClB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;","names":[]}