@react-email/render 0.0.17-canary.1 → 0.0.18-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.
package/dist/index.mjs ADDED
@@ -0,0 +1,853 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __async = (__this, __arguments, generator) => {
18
+ return new Promise((resolve, reject) => {
19
+ var fulfilled = (value) => {
20
+ try {
21
+ step(generator.next(value));
22
+ } catch (e) {
23
+ reject(e);
24
+ }
25
+ };
26
+ var rejected = (value) => {
27
+ try {
28
+ step(generator.throw(value));
29
+ } catch (e) {
30
+ reject(e);
31
+ }
32
+ };
33
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
34
+ step((generator = generator.apply(__this, __arguments)).next());
35
+ });
36
+ };
37
+
38
+ // src/render.ts
39
+ import { ConcurrentRoot } from "react-reconciler/constants";
40
+ import { convert } from "html-to-text";
41
+
42
+ // src/renderer/index.ts
43
+ import createReconciler from "react-reconciler";
44
+ import { DefaultEventPriority } from "react-reconciler/constants.js";
45
+
46
+ // src/renderer/dom-property.ts
47
+ var RESERVED = 0;
48
+ var STRING = 1;
49
+ var BOOLEANISH_STRING = 2;
50
+ var BOOLEAN = 3;
51
+ var OVERLOADED_BOOLEAN = 4;
52
+ var NUMERIC = 5;
53
+ var POSITIVE_NUMERIC = 6;
54
+ var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
55
+ var ATTRIBUTE_NAME_CHAR = `${ATTRIBUTE_NAME_START_CHAR}\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040`;
56
+ var VALID_ATTRIBUTE_NAME_REGEX = new RegExp(
57
+ `^[${ATTRIBUTE_NAME_START_CHAR}][${ATTRIBUTE_NAME_CHAR}]*$`
58
+ );
59
+ function shouldIgnoreAttribute(name, propertyInfo) {
60
+ if (propertyInfo !== null) {
61
+ return propertyInfo.type === RESERVED;
62
+ }
63
+ if (name.length > 2 && (name.startsWith("o") || name.startsWith("O")) && (name[1] === "n" || name[1] === "N")) {
64
+ return true;
65
+ }
66
+ return false;
67
+ }
68
+ function getPropertyInfo(name) {
69
+ return Object.hasOwn(properties, name) ? properties[name] : null;
70
+ }
71
+ var PropertyInfoRecord = class {
72
+ constructor(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
73
+ this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
74
+ this.attributeName = attributeName;
75
+ this.attributeNamespace = attributeNamespace;
76
+ this.mustUseProperty = mustUseProperty;
77
+ this.propertyName = name;
78
+ this.type = type;
79
+ this.sanitizeURL = sanitizeURL;
80
+ this.removeEmptyString = removeEmptyString;
81
+ }
82
+ };
83
+ var properties = {};
84
+ var reservedProps = [
85
+ "children",
86
+ "dangerouslySetInnerHTML",
87
+ // TODO: This prevents the assignment of defaultValue to regular
88
+ // elements (not just inputs). Now that ReactDOMInput assigns to the
89
+ // defaultValue property -- do we need this?
90
+ "defaultValue",
91
+ "defaultChecked",
92
+ "innerHTML",
93
+ "suppressContentEditableWarning",
94
+ "suppressHydrationWarning"
95
+ ];
96
+ reservedProps.forEach((name) => {
97
+ properties[name] = new PropertyInfoRecord(
98
+ name,
99
+ RESERVED,
100
+ false,
101
+ // mustUseProperty
102
+ name,
103
+ // attributeName
104
+ null,
105
+ // attributeNamespace
106
+ false,
107
+ // sanitizeURL
108
+ false
109
+ // removeEmptyString
110
+ );
111
+ });
112
+ [
113
+ ["acceptCharset", "accept-charset"],
114
+ ["className", "class"],
115
+ ["htmlFor", "for"],
116
+ ["httpEquiv", "http-equiv"]
117
+ ].forEach(([name, attributeName]) => {
118
+ properties[name] = new PropertyInfoRecord(
119
+ name,
120
+ STRING,
121
+ false,
122
+ // mustUseProperty
123
+ attributeName,
124
+ // attributeName
125
+ null,
126
+ // attributeNamespace
127
+ false,
128
+ // sanitizeURL
129
+ false
130
+ // removeEmptyString
131
+ );
132
+ });
133
+ ["contentEditable", "draggable", "spellCheck", "value"].forEach((name) => {
134
+ properties[name] = new PropertyInfoRecord(
135
+ name,
136
+ BOOLEANISH_STRING,
137
+ false,
138
+ // mustUseProperty
139
+ name.toLowerCase(),
140
+ // attributeName
141
+ null,
142
+ // attributeNamespace
143
+ false,
144
+ // sanitizeURL
145
+ false
146
+ // removeEmptyString
147
+ );
148
+ });
149
+ [
150
+ "autoReverse",
151
+ "externalResourcesRequired",
152
+ "focusable",
153
+ "preserveAlpha"
154
+ ].forEach((name) => {
155
+ properties[name] = new PropertyInfoRecord(
156
+ name,
157
+ BOOLEANISH_STRING,
158
+ false,
159
+ // mustUseProperty
160
+ name,
161
+ // attributeName
162
+ null,
163
+ // attributeNamespace
164
+ false,
165
+ // sanitizeURL
166
+ false
167
+ // removeEmptyString
168
+ );
169
+ });
170
+ [
171
+ "allowFullScreen",
172
+ "async",
173
+ // Note: there is a special case that prevents it from being written to the DOM
174
+ // on the client side because the browsers are inconsistent. Instead we call focus().
175
+ "autoFocus",
176
+ "autoPlay",
177
+ "controls",
178
+ "default",
179
+ "defer",
180
+ "disabled",
181
+ "disablePictureInPicture",
182
+ "disableRemotePlayback",
183
+ "formNoValidate",
184
+ "hidden",
185
+ "loop",
186
+ "noModule",
187
+ "noValidate",
188
+ "open",
189
+ "playsInline",
190
+ "readOnly",
191
+ "required",
192
+ "reversed",
193
+ "scoped",
194
+ "seamless",
195
+ // Microdata
196
+ "itemScope"
197
+ ].forEach((name) => {
198
+ properties[name] = new PropertyInfoRecord(
199
+ name,
200
+ BOOLEAN,
201
+ false,
202
+ // mustUseProperty
203
+ name.toLowerCase(),
204
+ // attributeName
205
+ null,
206
+ // attributeNamespace
207
+ false,
208
+ // sanitizeURL
209
+ false
210
+ // removeEmptyString
211
+ );
212
+ });
213
+ [
214
+ "checked",
215
+ // Note: `option.selected` is not updated if `select.multiple` is
216
+ // disabled with `removeAttribute`. We have special logic for handling this.
217
+ "multiple",
218
+ "muted",
219
+ "selected"
220
+ // NOTE: if you add a camelCased prop to this list,
221
+ // you'll need to set attributeName to name.toLowerCase()
222
+ // instead in the assignment below.
223
+ ].forEach((name) => {
224
+ properties[name] = new PropertyInfoRecord(
225
+ name,
226
+ BOOLEAN,
227
+ true,
228
+ // mustUseProperty
229
+ name,
230
+ // attributeName
231
+ null,
232
+ // attributeNamespace
233
+ false,
234
+ // sanitizeURL
235
+ false
236
+ // removeEmptyString
237
+ );
238
+ });
239
+ [
240
+ "capture",
241
+ "download"
242
+ // NOTE: if you add a camelCased prop to this list,
243
+ // you'll need to set attributeName to name.toLowerCase()
244
+ // instead in the assignment below.
245
+ ].forEach((name) => {
246
+ properties[name] = new PropertyInfoRecord(
247
+ name,
248
+ OVERLOADED_BOOLEAN,
249
+ false,
250
+ // mustUseProperty
251
+ name,
252
+ // attributeName
253
+ null,
254
+ // attributeNamespace
255
+ false,
256
+ // sanitizeURL
257
+ false
258
+ // removeEmptyString
259
+ );
260
+ });
261
+ [
262
+ "cols",
263
+ "rows",
264
+ "size",
265
+ "span"
266
+ // NOTE: if you add a camelCased prop to this list,
267
+ // you'll need to set attributeName to name.toLowerCase()
268
+ // instead in the assignment below.
269
+ ].forEach((name) => {
270
+ properties[name] = new PropertyInfoRecord(
271
+ name,
272
+ POSITIVE_NUMERIC,
273
+ false,
274
+ // mustUseProperty
275
+ name,
276
+ // attributeName
277
+ null,
278
+ // attributeNamespace
279
+ false,
280
+ // sanitizeURL
281
+ false
282
+ // removeEmptyString
283
+ );
284
+ });
285
+ ["rowSpan", "start"].forEach((name) => {
286
+ properties[name] = new PropertyInfoRecord(
287
+ name,
288
+ NUMERIC,
289
+ false,
290
+ // mustUseProperty
291
+ name.toLowerCase(),
292
+ // attributeName
293
+ null,
294
+ // attributeNamespace
295
+ false,
296
+ // sanitizeURL
297
+ false
298
+ // removeEmptyString
299
+ );
300
+ });
301
+ var CAMELIZE = /[-:]([a-z])/g;
302
+ var capitalize = (token) => token[1].toUpperCase();
303
+ [
304
+ "accent-height",
305
+ "alignment-baseline",
306
+ "arabic-form",
307
+ "baseline-shift",
308
+ "cap-height",
309
+ "clip-path",
310
+ "clip-rule",
311
+ "color-interpolation",
312
+ "color-interpolation-filters",
313
+ "color-profile",
314
+ "color-rendering",
315
+ "dominant-baseline",
316
+ "enable-background",
317
+ "fill-opacity",
318
+ "fill-rule",
319
+ "flood-color",
320
+ "flood-opacity",
321
+ "font-family",
322
+ "font-size",
323
+ "font-size-adjust",
324
+ "font-stretch",
325
+ "font-style",
326
+ "font-variant",
327
+ "font-weight",
328
+ "glyph-name",
329
+ "glyph-orientation-horizontal",
330
+ "glyph-orientation-vertical",
331
+ "horiz-adv-x",
332
+ "horiz-origin-x",
333
+ "image-rendering",
334
+ "letter-spacing",
335
+ "lighting-color",
336
+ "marker-end",
337
+ "marker-mid",
338
+ "marker-start",
339
+ "overline-position",
340
+ "overline-thickness",
341
+ "paint-order",
342
+ "panose-1",
343
+ "pointer-events",
344
+ "rendering-intent",
345
+ "shape-rendering",
346
+ "stop-color",
347
+ "stop-opacity",
348
+ "strikethrough-position",
349
+ "strikethrough-thickness",
350
+ "stroke-dasharray",
351
+ "stroke-dashoffset",
352
+ "stroke-linecap",
353
+ "stroke-linejoin",
354
+ "stroke-miterlimit",
355
+ "stroke-opacity",
356
+ "stroke-width",
357
+ "text-anchor",
358
+ "text-decoration",
359
+ "text-rendering",
360
+ "underline-position",
361
+ "underline-thickness",
362
+ "unicode-bidi",
363
+ "unicode-range",
364
+ "units-per-em",
365
+ "v-alphabetic",
366
+ "v-hanging",
367
+ "v-ideographic",
368
+ "v-mathematical",
369
+ "vector-effect",
370
+ "vert-adv-y",
371
+ "vert-origin-x",
372
+ "vert-origin-y",
373
+ "word-spacing",
374
+ "writing-mode",
375
+ "xmlns:xlink",
376
+ "x-height"
377
+ // NOTE: if you add a camelCased prop to this list,
378
+ // you'll need to set attributeName to name.toLowerCase()
379
+ // instead in the assignment below.
380
+ ].forEach((attributeName) => {
381
+ const name = attributeName.replace(CAMELIZE, capitalize);
382
+ properties[name] = new PropertyInfoRecord(
383
+ name,
384
+ STRING,
385
+ false,
386
+ // mustUseProperty
387
+ attributeName,
388
+ null,
389
+ // attributeNamespace
390
+ false,
391
+ // sanitizeURL
392
+ false
393
+ // removeEmptyString
394
+ );
395
+ });
396
+ [
397
+ "xlink:actuate",
398
+ "xlink:arcrole",
399
+ "xlink:role",
400
+ "xlink:show",
401
+ "xlink:title",
402
+ "xlink:type"
403
+ // NOTE: if you add a camelCased prop to this list,
404
+ // you'll need to set attributeName to name.toLowerCase()
405
+ // instead in the assignment below.
406
+ ].forEach((attributeName) => {
407
+ const name = attributeName.replace(CAMELIZE, capitalize);
408
+ properties[name] = new PropertyInfoRecord(
409
+ name,
410
+ STRING,
411
+ false,
412
+ // mustUseProperty
413
+ attributeName,
414
+ "http://www.w3.org/1999/xlink",
415
+ false,
416
+ // sanitizeURL
417
+ false
418
+ // removeEmptyString
419
+ );
420
+ });
421
+ [
422
+ "xml:base",
423
+ "xml:lang",
424
+ "xml:space"
425
+ // NOTE: if you add a camelCased prop to this list,
426
+ // you'll need to set attributeName to name.toLowerCase()
427
+ // instead in the assignment below.
428
+ ].forEach((attributeName) => {
429
+ const name = attributeName.replace(CAMELIZE, capitalize);
430
+ properties[name] = new PropertyInfoRecord(
431
+ name,
432
+ STRING,
433
+ false,
434
+ // mustUseProperty
435
+ attributeName,
436
+ "http://www.w3.org/XML/1998/namespace",
437
+ false,
438
+ // sanitizeURL
439
+ false
440
+ // removeEmptyString
441
+ );
442
+ });
443
+ ["tabIndex", "crossOrigin"].forEach((attributeName) => {
444
+ properties[attributeName] = new PropertyInfoRecord(
445
+ attributeName,
446
+ STRING,
447
+ false,
448
+ // mustUseProperty
449
+ attributeName.toLowerCase(),
450
+ // attributeName
451
+ null,
452
+ // attributeNamespace
453
+ false,
454
+ // sanitizeURL
455
+ false
456
+ // removeEmptyString
457
+ );
458
+ });
459
+ var xlinkHref = "xlinkHref";
460
+ properties[xlinkHref] = new PropertyInfoRecord(
461
+ "xlinkHref",
462
+ STRING,
463
+ false,
464
+ // mustUseProperty
465
+ "xlink:href",
466
+ "http://www.w3.org/1999/xlink",
467
+ true,
468
+ // sanitizeURL
469
+ false
470
+ // removeEmptyString
471
+ );
472
+ ["src", "href", "action", "formAction"].forEach((attributeName) => {
473
+ properties[attributeName] = new PropertyInfoRecord(
474
+ attributeName,
475
+ STRING,
476
+ false,
477
+ // mustUseProperty
478
+ attributeName.toLowerCase(),
479
+ // attributeName
480
+ null,
481
+ // attributeNamespace
482
+ true,
483
+ // sanitizeURL
484
+ true
485
+ // removeEmptyString
486
+ );
487
+ });
488
+
489
+ // src/renderer/unitless-css-properties.ts
490
+ var isPropWithUnitlessNumber = {
491
+ animationIterationCount: true,
492
+ aspectRatio: true,
493
+ borderImageOutset: true,
494
+ borderImageSlice: true,
495
+ borderImageWidth: true,
496
+ boxFlex: true,
497
+ boxFlexGroup: true,
498
+ boxOrdinalGroup: true,
499
+ columnCount: true,
500
+ columns: true,
501
+ flex: true,
502
+ flexGrow: true,
503
+ flexPositive: true,
504
+ flexShrink: true,
505
+ flexNegative: true,
506
+ flexOrder: true,
507
+ gridArea: true,
508
+ gridRow: true,
509
+ gridRowEnd: true,
510
+ gridRowSpan: true,
511
+ gridRowStart: true,
512
+ gridColumn: true,
513
+ gridColumnEnd: true,
514
+ gridColumnSpan: true,
515
+ gridColumnStart: true,
516
+ fontWeight: true,
517
+ lineClamp: true,
518
+ lineHeight: true,
519
+ opacity: true,
520
+ order: true,
521
+ orphans: true,
522
+ tabSize: true,
523
+ widows: true,
524
+ zIndex: true,
525
+ zoom: true,
526
+ // SVG-related properties
527
+ fillOpacity: true,
528
+ floodOpacity: true,
529
+ stopOpacity: true,
530
+ strokeDasharray: true,
531
+ strokeDashoffset: true,
532
+ strokeMiterlimit: true,
533
+ strokeOpacity: true,
534
+ strokeWidth: true
535
+ };
536
+ function propWithPrefix(prefix, prop) {
537
+ return prefix + prop.charAt(0).toUpperCase() + prop.substring(1);
538
+ }
539
+ var prefixes = ["Webkit", "ms", "Moz", "O"];
540
+ for (const key in isPropWithUnitlessNumber) {
541
+ const prop = key;
542
+ for (const prefix of prefixes) {
543
+ isPropWithUnitlessNumber[propWithPrefix(prefix, prop)] = isPropWithUnitlessNumber[prop];
544
+ }
545
+ }
546
+
547
+ // src/renderer/property-mapping.ts
548
+ function convertPropsIntoAttributes(props) {
549
+ return Object.keys(props).filter((key) => !key.startsWith("on") && key !== "children").map((originalKey) => {
550
+ const propertyInfo = getPropertyInfo(originalKey);
551
+ if (shouldIgnoreAttribute(originalKey, propertyInfo)) {
552
+ return void 0;
553
+ }
554
+ const value = props[originalKey];
555
+ if (value === void 0 || value === null)
556
+ return "";
557
+ const propertyName = propertyInfo ? propertyInfo.attributeName : originalKey;
558
+ if (typeof value === "string") {
559
+ return `${propertyName}="${value}"`;
560
+ }
561
+ if (propertyName === "style" && typeof value === "object") {
562
+ return convertStyleIntoAttribute(value);
563
+ }
564
+ if (typeof value === "object") {
565
+ return `${propertyName}="${JSON.stringify(value)}"`;
566
+ }
567
+ return `${propertyName}="${value}"`;
568
+ }).filter(Boolean).join(" ");
569
+ }
570
+ function convertStyleIntoAttribute(style) {
571
+ const inlineStyles = Object.entries(style).map(([key, value]) => {
572
+ let valueToUse = `${value}`;
573
+ if (typeof value === "number" && value !== 0 && !isPropWithUnitlessNumber[key]) {
574
+ valueToUse = `${value}px`;
575
+ }
576
+ valueToUse = valueToUse.trim();
577
+ valueToUse = valueToUse.replaceAll('"', "'");
578
+ if (key.startsWith("ms")) {
579
+ return `${fromCamelCaseToSnakeCase(key)}:${valueToUse}`;
580
+ }
581
+ return `${fromCamelCaseToSnakeCase(key)}:${valueToUse}`;
582
+ }).join(";");
583
+ return `style="${inlineStyles}"`;
584
+ }
585
+ function fromCamelCaseToSnakeCase(camelCasedText) {
586
+ return camelCasedText.replaceAll(
587
+ /([a-z])([A-Z])/g,
588
+ (_match, lowerCaseLetter, upperCaseLetter) => {
589
+ return `${lowerCaseLetter}-${upperCaseLetter.toLowerCase()}`;
590
+ }
591
+ );
592
+ }
593
+
594
+ // src/renderer/nodes/node.ts
595
+ var ParentNode = class {
596
+ constructor(id, internalChildren) {
597
+ this.id = id;
598
+ this.internalChildren = internalChildren;
599
+ }
600
+ removeChild(child) {
601
+ child.parent = void 0;
602
+ this.internalChildren = this.internalChildren.filter(
603
+ (otherChild) => otherChild.id !== child.id
604
+ );
605
+ }
606
+ insertBefore(toInsert, nodeToInsertBeforeOf) {
607
+ const index = this.internalChildren.findIndex(
608
+ (node) => node.id === nodeToInsertBeforeOf.id
609
+ );
610
+ if (index > -1) {
611
+ toInsert.parent = this;
612
+ this.internalChildren.splice(index, 0, toInsert);
613
+ }
614
+ }
615
+ appendChild(child) {
616
+ child.parent = this;
617
+ this.internalChildren.push(child);
618
+ }
619
+ get children() {
620
+ return this.internalChildren;
621
+ }
622
+ };
623
+
624
+ // src/renderer/nodes/element-node.ts
625
+ var ElementNode = class extends ParentNode {
626
+ constructor(tag, props) {
627
+ super(Symbol("ElementNode"), []);
628
+ this.hidden = false;
629
+ this.internalTag = tag;
630
+ this.props = props;
631
+ }
632
+ get tag() {
633
+ return this.internalTag;
634
+ }
635
+ get html() {
636
+ if (this.hidden)
637
+ return "";
638
+ const attributes = convertPropsIntoAttributes(this.props);
639
+ const attributePortion = attributes.trim().length > 0 ? ` ${attributes}` : "";
640
+ if (/^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/.test(
641
+ this.internalTag.toUpperCase()
642
+ )) {
643
+ return `<${this.internalTag}${attributePortion}/>`;
644
+ }
645
+ let childrenPortion;
646
+ if ("dangerouslySetInnerHTML" in this.props && typeof this.props.dangerouslySetInnerHTML === "object" && this.props.dangerouslySetInnerHTML !== null && "__html" in this.props.dangerouslySetInnerHTML && typeof this.props.dangerouslySetInnerHTML.__html === "string") {
647
+ childrenPortion = this.props.dangerouslySetInnerHTML.__html;
648
+ } else {
649
+ childrenPortion = this.internalChildren.map((child) => child.html).join("");
650
+ }
651
+ return `<${this.internalTag}${attributePortion}>${childrenPortion}</${this.internalTag}>`;
652
+ }
653
+ get children() {
654
+ return this.internalChildren;
655
+ }
656
+ };
657
+
658
+ // src/renderer/nodes/text-node.ts
659
+ var TextNode = class {
660
+ constructor(text) {
661
+ this.id = Symbol("TextNode");
662
+ this.hidden = false;
663
+ this.text = text;
664
+ }
665
+ get html() {
666
+ if (this.hidden)
667
+ return "";
668
+ return this.text;
669
+ }
670
+ };
671
+
672
+ // src/renderer/index.ts
673
+ var renderer = createReconciler({
674
+ isPrimaryRenderer: true,
675
+ supportsMutation: true,
676
+ supportsPersistence: false,
677
+ supportsHydration: true,
678
+ supportsMicrotasks: true,
679
+ scheduleMicrotask: queueMicrotask,
680
+ scheduleTimeout: setTimeout,
681
+ cancelTimeout: clearTimeout,
682
+ noTimeout: -1,
683
+ appendChildToContainer(container, child) {
684
+ container.appendChild(child);
685
+ },
686
+ insertInContainerBefore(container, child, beforeChild) {
687
+ container.insertBefore(child, beforeChild);
688
+ },
689
+ appendInitialChild(parent, child) {
690
+ parent.appendChild(child);
691
+ },
692
+ insertBefore(parent, child, beforeChild) {
693
+ parent.insertBefore(child, beforeChild);
694
+ },
695
+ appendChild(parent, child) {
696
+ parent.appendChild(child);
697
+ },
698
+ removeChild(node, removeNode) {
699
+ node.removeChild(removeNode);
700
+ },
701
+ removeChildFromContainer(container, node) {
702
+ container.removeChild(node);
703
+ },
704
+ clearContainer: (container) => {
705
+ for (const child of container.children) {
706
+ container.removeChild(child);
707
+ }
708
+ },
709
+ getRootHostContext: () => ({}),
710
+ createInstance(type, props) {
711
+ return new ElementNode(type, props);
712
+ },
713
+ createTextInstance(text) {
714
+ return new TextNode(text);
715
+ },
716
+ prepareForCommit: () => null,
717
+ preparePortalMount: () => null,
718
+ commitTextUpdate(node, _oldText, newText) {
719
+ node.text = newText;
720
+ },
721
+ resetAfterCommit() {
722
+ },
723
+ getChildHostContext(parentHostContext) {
724
+ return parentHostContext;
725
+ },
726
+ shouldSetTextContent: () => false,
727
+ resetTextContent() {
728
+ },
729
+ hideTextInstance(node) {
730
+ node.hidden = true;
731
+ },
732
+ unhideTextInstance(node) {
733
+ node.hidden = false;
734
+ },
735
+ getPublicInstance: (instance) => instance,
736
+ hideInstance(node) {
737
+ node.hidden = true;
738
+ },
739
+ unhideInstance(node) {
740
+ node.hidden = false;
741
+ },
742
+ finalizeInitialChildren: () => false,
743
+ getCurrentEventPriority: () => DefaultEventPriority,
744
+ beforeActiveInstanceBlur() {
745
+ },
746
+ afterActiveInstanceBlur() {
747
+ },
748
+ detachDeletedInstance() {
749
+ },
750
+ getInstanceFromNode: () => null,
751
+ prepareScopeUpdate() {
752
+ },
753
+ getInstanceFromScope: () => null,
754
+ prepareUpdate() {
755
+ return null;
756
+ },
757
+ commitUpdate() {
758
+ }
759
+ });
760
+
761
+ // src/renderer/nodes/root.ts
762
+ var Root = class extends ParentNode {
763
+ constructor() {
764
+ super(Symbol("RootNode"), []);
765
+ }
766
+ get html() {
767
+ return this.internalChildren.map((child) => child.html).join("");
768
+ }
769
+ };
770
+
771
+ // src/plain-text-selectors.ts
772
+ var plainTextSelectors = [
773
+ { selector: "img", format: "skip" },
774
+ { selector: "#__react-email-preview", format: "skip" },
775
+ {
776
+ selector: "a",
777
+ options: { linkBrackets: false }
778
+ }
779
+ ];
780
+
781
+ // src/utils/pretty.ts
782
+ import jsBeautify from "js-beautify";
783
+ var defaults = {
784
+ unformatted: ["code", "pre", "em", "strong", "span"],
785
+ indent_inner_html: true,
786
+ indent_char: " ",
787
+ indent_size: 2,
788
+ sep: "\n"
789
+ };
790
+ var pretty = (str, options = {}) => {
791
+ return jsBeautify.html(str, __spreadValues(__spreadValues({}, defaults), options));
792
+ };
793
+
794
+ // src/render.ts
795
+ function checkIfAllSuspensesAreDone(fiber) {
796
+ if (fiber.tag === 13 && fiber.memoizedState !== null) {
797
+ return false;
798
+ }
799
+ let child = fiber.child;
800
+ while (child !== null) {
801
+ if (!checkIfAllSuspensesAreDone(child)) {
802
+ return false;
803
+ }
804
+ child = child.sibling;
805
+ }
806
+ return true;
807
+ }
808
+ var renderToMarkup = (element) => {
809
+ return new Promise((resolve, reject) => {
810
+ const root = new Root();
811
+ const container = renderer.createContainer(
812
+ root,
813
+ ConcurrentRoot,
814
+ {},
815
+ false,
816
+ true,
817
+ "",
818
+ (err) => {
819
+ reject(err);
820
+ },
821
+ {}
822
+ );
823
+ renderer.updateContainer(element, container, null, () => {
824
+ function checkCompletion() {
825
+ if (checkIfAllSuspensesAreDone(container.current)) {
826
+ resolve(root.html);
827
+ } else {
828
+ setTimeout(checkCompletion, 0);
829
+ }
830
+ }
831
+ checkCompletion();
832
+ });
833
+ });
834
+ };
835
+ var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
836
+ var render = (element, options) => __async(void 0, null, function* () {
837
+ const markup = yield renderToMarkup(element);
838
+ const document = `${doctype}${markup}`;
839
+ if (options == null ? void 0 : options.plainText) {
840
+ return convert(document, __spreadValues({
841
+ selectors: plainTextSelectors
842
+ }, options.htmlToTextOptions));
843
+ }
844
+ if (options == null ? void 0 : options.pretty) {
845
+ return pretty(document);
846
+ }
847
+ return document;
848
+ });
849
+ export {
850
+ doctype,
851
+ plainTextSelectors,
852
+ render
853
+ };