@react-email/render 1.0.0 → 1.0.2-canary.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.
@@ -15,9 +15,9 @@ type Options = {
15
15
  htmlToTextOptions?: HtmlToTextOptions;
16
16
  });
17
17
 
18
- declare const render: (component: React.ReactElement, options?: Options) => Promise<string>;
18
+ declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
19
19
 
20
- declare const renderAsync: (component: React.ReactElement, options?: Options) => Promise<string>;
20
+ declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
21
21
 
22
22
  declare const plainTextSelectors: SelectorDefinition[];
23
23
 
@@ -15,9 +15,9 @@ type Options = {
15
15
  htmlToTextOptions?: HtmlToTextOptions;
16
16
  });
17
17
 
18
- declare const render: (component: React.ReactElement, options?: Options) => Promise<string>;
18
+ declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
19
19
 
20
- declare const renderAsync: (component: React.ReactElement, options?: Options) => Promise<string>;
20
+ declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
21
21
 
22
22
  declare const plainTextSelectors: SelectorDefinition[];
23
23
 
@@ -70,8 +70,9 @@ __export(browser_exports, {
70
70
  });
71
71
  module.exports = __toCommonJS(browser_exports);
72
72
 
73
- // src/browser/render.ts
73
+ // src/browser/render.tsx
74
74
  var import_html_to_text = require("html-to-text");
75
+ var import_react = require("react");
75
76
 
76
77
  // src/shared/utils/pretty.ts
77
78
  var import_js_beautify = __toESM(require("js-beautify"));
@@ -96,14 +97,15 @@ var plainTextSelectors = [
96
97
  }
97
98
  ];
98
99
 
99
- // src/browser/render.ts
100
+ // src/browser/render.tsx
101
+ var import_jsx_runtime = require("react/jsx-runtime");
100
102
  var decoder = new TextDecoder("utf-8");
101
103
  var readStream = (stream) => __async(void 0, null, function* () {
102
- let result = "";
104
+ const chunks = [];
103
105
  if ("pipeTo" in stream) {
104
106
  const writableStream = new WritableStream({
105
107
  write(chunk) {
106
- result += decoder.decode(chunk);
108
+ chunks.push(chunk);
107
109
  }
108
110
  });
109
111
  yield stream.pipeTo(writableStream);
@@ -117,18 +119,29 @@ var readStream = (stream) => __async(void 0, null, function* () {
117
119
  }
118
120
  );
119
121
  }
120
- return result;
122
+ let length = 0;
123
+ chunks.forEach((item) => {
124
+ length += item.length;
125
+ });
126
+ const mergedChunks = new Uint8Array(length);
127
+ let offset = 0;
128
+ chunks.forEach((item) => {
129
+ mergedChunks.set(item, offset);
130
+ offset += item.length;
131
+ });
132
+ return decoder.decode(mergedChunks);
121
133
  });
122
- var render = (component, options) => __async(void 0, null, function* () {
134
+ var render = (element, options) => __async(void 0, null, function* () {
135
+ const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
123
136
  const { default: reactDOMServer } = yield import("react-dom/server");
124
137
  let html;
125
138
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
126
139
  html = yield readStream(
127
- yield reactDOMServer.renderToReadableStream(component)
140
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
128
141
  );
129
142
  } else {
130
143
  yield new Promise((resolve, reject) => {
131
- const stream = reactDOMServer.renderToPipeableStream(component, {
144
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
132
145
  onAllReady() {
133
146
  return __async(this, null, function* () {
134
147
  html = yield readStream(stream);
@@ -154,15 +167,18 @@ var render = (component, options) => __async(void 0, null, function* () {
154
167
  return document;
155
168
  });
156
169
 
157
- // src/browser/render-async.ts
170
+ // src/browser/render-async.tsx
158
171
  var import_html_to_text2 = require("html-to-text");
172
+ var import_react2 = require("react");
173
+
174
+ // src/browser/read-stream.ts
159
175
  var decoder2 = new TextDecoder("utf-8");
160
176
  var readStream2 = (stream) => __async(void 0, null, function* () {
161
- let result = "";
177
+ const chunks = [];
162
178
  if ("pipeTo" in stream) {
163
179
  const writableStream = new WritableStream({
164
180
  write(chunk) {
165
- result += decoder2.decode(chunk);
181
+ chunks.push(chunk);
166
182
  }
167
183
  });
168
184
  yield stream.pipeTo(writableStream);
@@ -176,18 +192,32 @@ var readStream2 = (stream) => __async(void 0, null, function* () {
176
192
  }
177
193
  );
178
194
  }
179
- return result;
195
+ let length = 0;
196
+ chunks.forEach((item) => {
197
+ length += item.length;
198
+ });
199
+ const mergedChunks = new Uint8Array(length);
200
+ let offset = 0;
201
+ chunks.forEach((item) => {
202
+ mergedChunks.set(item, offset);
203
+ offset += item.length;
204
+ });
205
+ return decoder2.decode(mergedChunks);
180
206
  });
181
- var renderAsync = (component, options) => __async(void 0, null, function* () {
207
+
208
+ // src/browser/render-async.tsx
209
+ var import_jsx_runtime2 = require("react/jsx-runtime");
210
+ var renderAsync = (element, options) => __async(void 0, null, function* () {
211
+ const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
182
212
  const { default: reactDOMServer } = yield import("react-dom/server");
183
213
  let html;
184
214
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
185
215
  html = yield readStream2(
186
- yield reactDOMServer.renderToReadableStream(component)
216
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
187
217
  );
188
218
  } else {
189
219
  yield new Promise((resolve, reject) => {
190
- const stream = reactDOMServer.renderToPipeableStream(component, {
220
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
191
221
  onAllReady() {
192
222
  return __async(this, null, function* () {
193
223
  html = yield readStream2(stream);
@@ -35,8 +35,9 @@ var __async = (__this, __arguments, generator) => {
35
35
  });
36
36
  };
37
37
 
38
- // src/browser/render.ts
38
+ // src/browser/render.tsx
39
39
  import { convert } from "html-to-text";
40
+ import { Suspense } from "react";
40
41
 
41
42
  // src/shared/utils/pretty.ts
42
43
  import jsBeautify from "js-beautify";
@@ -61,14 +62,15 @@ var plainTextSelectors = [
61
62
  }
62
63
  ];
63
64
 
64
- // src/browser/render.ts
65
+ // src/browser/render.tsx
66
+ import { jsx } from "react/jsx-runtime";
65
67
  var decoder = new TextDecoder("utf-8");
66
68
  var readStream = (stream) => __async(void 0, null, function* () {
67
- let result = "";
69
+ const chunks = [];
68
70
  if ("pipeTo" in stream) {
69
71
  const writableStream = new WritableStream({
70
72
  write(chunk) {
71
- result += decoder.decode(chunk);
73
+ chunks.push(chunk);
72
74
  }
73
75
  });
74
76
  yield stream.pipeTo(writableStream);
@@ -82,18 +84,29 @@ var readStream = (stream) => __async(void 0, null, function* () {
82
84
  }
83
85
  );
84
86
  }
85
- return result;
87
+ let length = 0;
88
+ chunks.forEach((item) => {
89
+ length += item.length;
90
+ });
91
+ const mergedChunks = new Uint8Array(length);
92
+ let offset = 0;
93
+ chunks.forEach((item) => {
94
+ mergedChunks.set(item, offset);
95
+ offset += item.length;
96
+ });
97
+ return decoder.decode(mergedChunks);
86
98
  });
87
- var render = (component, options) => __async(void 0, null, function* () {
99
+ var render = (element, options) => __async(void 0, null, function* () {
100
+ const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
88
101
  const { default: reactDOMServer } = yield import("react-dom/server");
89
102
  let html;
90
103
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
91
104
  html = yield readStream(
92
- yield reactDOMServer.renderToReadableStream(component)
105
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
93
106
  );
94
107
  } else {
95
108
  yield new Promise((resolve, reject) => {
96
- const stream = reactDOMServer.renderToPipeableStream(component, {
109
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
97
110
  onAllReady() {
98
111
  return __async(this, null, function* () {
99
112
  html = yield readStream(stream);
@@ -119,15 +132,18 @@ var render = (component, options) => __async(void 0, null, function* () {
119
132
  return document;
120
133
  });
121
134
 
122
- // src/browser/render-async.ts
135
+ // src/browser/render-async.tsx
123
136
  import { convert as convert2 } from "html-to-text";
137
+ import { Suspense as Suspense2 } from "react";
138
+
139
+ // src/browser/read-stream.ts
124
140
  var decoder2 = new TextDecoder("utf-8");
125
141
  var readStream2 = (stream) => __async(void 0, null, function* () {
126
- let result = "";
142
+ const chunks = [];
127
143
  if ("pipeTo" in stream) {
128
144
  const writableStream = new WritableStream({
129
145
  write(chunk) {
130
- result += decoder2.decode(chunk);
146
+ chunks.push(chunk);
131
147
  }
132
148
  });
133
149
  yield stream.pipeTo(writableStream);
@@ -141,18 +157,32 @@ var readStream2 = (stream) => __async(void 0, null, function* () {
141
157
  }
142
158
  );
143
159
  }
144
- return result;
160
+ let length = 0;
161
+ chunks.forEach((item) => {
162
+ length += item.length;
163
+ });
164
+ const mergedChunks = new Uint8Array(length);
165
+ let offset = 0;
166
+ chunks.forEach((item) => {
167
+ mergedChunks.set(item, offset);
168
+ offset += item.length;
169
+ });
170
+ return decoder2.decode(mergedChunks);
145
171
  });
146
- var renderAsync = (component, options) => __async(void 0, null, function* () {
172
+
173
+ // src/browser/render-async.tsx
174
+ import { jsx as jsx2 } from "react/jsx-runtime";
175
+ var renderAsync = (element, options) => __async(void 0, null, function* () {
176
+ const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
147
177
  const { default: reactDOMServer } = yield import("react-dom/server");
148
178
  let html;
149
179
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
150
180
  html = yield readStream2(
151
- yield reactDOMServer.renderToReadableStream(component)
181
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
152
182
  );
153
183
  } else {
154
184
  yield new Promise((resolve, reject) => {
155
- const stream = reactDOMServer.renderToPipeableStream(component, {
185
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
156
186
  onAllReady() {
157
187
  return __async(this, null, function* () {
158
188
  html = yield readStream2(stream);
@@ -15,12 +15,12 @@ type Options = {
15
15
  htmlToTextOptions?: HtmlToTextOptions;
16
16
  });
17
17
 
18
- declare const render: (component: React.ReactElement, options?: Options) => Promise<string>;
18
+ declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
19
19
 
20
20
  /**
21
21
  * @deprecated use `render`
22
22
  */
23
- declare const renderAsync: (component: React.ReactElement, options?: Options) => Promise<string>;
23
+ declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
24
24
 
25
25
  declare const plainTextSelectors: SelectorDefinition[];
26
26
 
@@ -15,12 +15,12 @@ type Options = {
15
15
  htmlToTextOptions?: HtmlToTextOptions;
16
16
  });
17
17
 
18
- declare const render: (component: React.ReactElement, options?: Options) => Promise<string>;
18
+ declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
19
19
 
20
20
  /**
21
21
  * @deprecated use `render`
22
22
  */
23
- declare const renderAsync: (component: React.ReactElement, options?: Options) => Promise<string>;
23
+ declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
24
24
 
25
25
  declare const plainTextSelectors: SelectorDefinition[];
26
26
 
@@ -70,9 +70,9 @@ __export(node_exports, {
70
70
  });
71
71
  module.exports = __toCommonJS(node_exports);
72
72
 
73
- // src/node/render.ts
74
- var import_node_stream = require("stream");
73
+ // src/node/render.tsx
75
74
  var import_html_to_text = require("html-to-text");
75
+ var import_react = require("react");
76
76
 
77
77
  // src/shared/utils/pretty.ts
78
78
  var import_js_beautify = __toESM(require("js-beautify"));
@@ -97,7 +97,8 @@ var plainTextSelectors = [
97
97
  }
98
98
  ];
99
99
 
100
- // src/node/render.ts
100
+ // src/node/read-stream.ts
101
+ var import_node_stream = require("stream");
101
102
  var decoder = new TextDecoder("utf-8");
102
103
  var readStream = (stream) => __async(void 0, null, function* () {
103
104
  let result = "";
@@ -125,16 +126,20 @@ var readStream = (stream) => __async(void 0, null, function* () {
125
126
  }
126
127
  return result;
127
128
  });
128
- var render = (component, options) => __async(void 0, null, function* () {
129
+
130
+ // src/node/render.tsx
131
+ var import_jsx_runtime = require("react/jsx-runtime");
132
+ var render = (element, options) => __async(void 0, null, function* () {
133
+ const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
129
134
  const { default: reactDOMServer } = yield import("react-dom/server");
130
135
  let html;
131
136
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
132
137
  html = yield readStream(
133
- yield reactDOMServer.renderToReadableStream(component)
138
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
134
139
  );
135
140
  } else {
136
141
  yield new Promise((resolve, reject) => {
137
- const stream = reactDOMServer.renderToPipeableStream(component, {
142
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
138
143
  onAllReady() {
139
144
  return __async(this, null, function* () {
140
145
  html = yield readStream(stream);
@@ -160,49 +165,24 @@ var render = (component, options) => __async(void 0, null, function* () {
160
165
  return document;
161
166
  });
162
167
 
163
- // src/node/render-async.ts
164
- var import_node_stream2 = require("stream");
168
+ // src/node/render-async.tsx
165
169
  var import_html_to_text2 = require("html-to-text");
166
- var decoder2 = new TextDecoder("utf-8");
167
- var readStream2 = (stream) => __async(void 0, null, function* () {
168
- let result = "";
169
- if ("pipeTo" in stream) {
170
- const writableStream = new WritableStream({
171
- write(chunk) {
172
- result += decoder2.decode(chunk);
173
- }
174
- });
175
- yield stream.pipeTo(writableStream);
176
- } else {
177
- const writable = new import_node_stream2.Writable({
178
- write(chunk, _encoding, callback) {
179
- result += decoder2.decode(chunk);
180
- callback();
181
- }
182
- });
183
- stream.pipe(writable);
184
- return new Promise((resolve, reject) => {
185
- writable.on("error", reject);
186
- writable.on("close", () => {
187
- resolve(result);
188
- });
189
- });
190
- }
191
- return result;
192
- });
193
- var renderAsync = (component, options) => __async(void 0, null, function* () {
170
+ var import_react2 = require("react");
171
+ var import_jsx_runtime2 = require("react/jsx-runtime");
172
+ var renderAsync = (element, options) => __async(void 0, null, function* () {
173
+ const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
194
174
  const { default: reactDOMServer } = yield import("react-dom/server");
195
175
  let html;
196
176
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
197
- html = yield readStream2(
198
- yield reactDOMServer.renderToReadableStream(component)
177
+ html = yield readStream(
178
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
199
179
  );
200
180
  } else {
201
181
  yield new Promise((resolve, reject) => {
202
- const stream = reactDOMServer.renderToPipeableStream(component, {
182
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
203
183
  onAllReady() {
204
184
  return __async(this, null, function* () {
205
- html = yield readStream2(stream);
185
+ html = yield readStream(stream);
206
186
  resolve();
207
187
  });
208
188
  },
@@ -35,9 +35,9 @@ var __async = (__this, __arguments, generator) => {
35
35
  });
36
36
  };
37
37
 
38
- // src/node/render.ts
39
- import { Writable } from "node:stream";
38
+ // src/node/render.tsx
40
39
  import { convert } from "html-to-text";
40
+ import { Suspense } from "react";
41
41
 
42
42
  // src/shared/utils/pretty.ts
43
43
  import jsBeautify from "js-beautify";
@@ -62,7 +62,8 @@ var plainTextSelectors = [
62
62
  }
63
63
  ];
64
64
 
65
- // src/node/render.ts
65
+ // src/node/read-stream.ts
66
+ import { Writable } from "node:stream";
66
67
  var decoder = new TextDecoder("utf-8");
67
68
  var readStream = (stream) => __async(void 0, null, function* () {
68
69
  let result = "";
@@ -90,16 +91,20 @@ var readStream = (stream) => __async(void 0, null, function* () {
90
91
  }
91
92
  return result;
92
93
  });
93
- var render = (component, options) => __async(void 0, null, function* () {
94
+
95
+ // src/node/render.tsx
96
+ import { jsx } from "react/jsx-runtime";
97
+ var render = (element, options) => __async(void 0, null, function* () {
98
+ const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
94
99
  const { default: reactDOMServer } = yield import("react-dom/server");
95
100
  let html;
96
101
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
97
102
  html = yield readStream(
98
- yield reactDOMServer.renderToReadableStream(component)
103
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
99
104
  );
100
105
  } else {
101
106
  yield new Promise((resolve, reject) => {
102
- const stream = reactDOMServer.renderToPipeableStream(component, {
107
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
103
108
  onAllReady() {
104
109
  return __async(this, null, function* () {
105
110
  html = yield readStream(stream);
@@ -125,49 +130,24 @@ var render = (component, options) => __async(void 0, null, function* () {
125
130
  return document;
126
131
  });
127
132
 
128
- // src/node/render-async.ts
129
- import { Writable as Writable2 } from "node:stream";
133
+ // src/node/render-async.tsx
130
134
  import { convert as convert2 } from "html-to-text";
131
- var decoder2 = new TextDecoder("utf-8");
132
- var readStream2 = (stream) => __async(void 0, null, function* () {
133
- let result = "";
134
- if ("pipeTo" in stream) {
135
- const writableStream = new WritableStream({
136
- write(chunk) {
137
- result += decoder2.decode(chunk);
138
- }
139
- });
140
- yield stream.pipeTo(writableStream);
141
- } else {
142
- const writable = new Writable2({
143
- write(chunk, _encoding, callback) {
144
- result += decoder2.decode(chunk);
145
- callback();
146
- }
147
- });
148
- stream.pipe(writable);
149
- return new Promise((resolve, reject) => {
150
- writable.on("error", reject);
151
- writable.on("close", () => {
152
- resolve(result);
153
- });
154
- });
155
- }
156
- return result;
157
- });
158
- var renderAsync = (component, options) => __async(void 0, null, function* () {
135
+ import { Suspense as Suspense2 } from "react";
136
+ import { jsx as jsx2 } from "react/jsx-runtime";
137
+ var renderAsync = (element, options) => __async(void 0, null, function* () {
138
+ const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
159
139
  const { default: reactDOMServer } = yield import("react-dom/server");
160
140
  let html;
161
141
  if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
162
- html = yield readStream2(
163
- yield reactDOMServer.renderToReadableStream(component)
142
+ html = yield readStream(
143
+ yield reactDOMServer.renderToReadableStream(suspendedElement)
164
144
  );
165
145
  } else {
166
146
  yield new Promise((resolve, reject) => {
167
- const stream = reactDOMServer.renderToPipeableStream(component, {
147
+ const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
168
148
  onAllReady() {
169
149
  return __async(this, null, function* () {
170
- html = yield readStream2(stream);
150
+ html = yield readStream(stream);
171
151
  resolve();
172
152
  });
173
153
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-email/render",
3
- "version": "1.0.0",
3
+ "version": "1.0.2-canary.0",
4
4
  "description": "Transform React components into HTML email templates",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/browser/index.js",
@@ -86,6 +86,8 @@
86
86
  "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
87
87
  },
88
88
  "devDependencies": {
89
+ "@types/react": "npm:types-react@19.0.0-rc.1",
90
+ "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
89
91
  "@edge-runtime/vm": "3.1.8",
90
92
  "@types/html-to-text": "9.0.4",
91
93
  "@types/js-beautify": "1.14.3",
package/readme.md CHANGED
@@ -35,7 +35,7 @@ Convert React components into a HTML string.
35
35
  import { MyTemplate } from "../components/MyTemplate";
36
36
  import { render } from "@react-email/render";
37
37
 
38
- const html = render(<MyTemplate firstName="Jim" />);
38
+ const html = await render(<MyTemplate firstName="Jim" />);
39
39
  ```
40
40
 
41
41
  ## License