hadars 0.1.40 → 0.2.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/README.md +1 -55
- package/dist/{chunk-2ENP7IAW.js → chunk-LY5MTHFV.js} +360 -203
- package/dist/cli.js +424 -262
- package/dist/lambda.cjs +387 -229
- package/dist/lambda.js +63 -45
- package/dist/slim-react/index.cjs +361 -203
- package/dist/slim-react/index.d.cts +24 -8
- package/dist/slim-react/index.d.ts +24 -8
- package/dist/slim-react/index.js +3 -1
- package/dist/ssr-render-worker.js +349 -219
- package/package.json +1 -1
- package/src/build.ts +7 -6
- package/src/lambda.ts +6 -2
- package/src/slim-react/context.ts +2 -1
- package/src/slim-react/index.ts +21 -18
- package/src/slim-react/render.ts +379 -240
- package/src/slim-react/renderContext.ts +105 -45
- package/src/ssr-render-worker.ts +10 -43
- package/src/utils/cookies.ts +1 -1
- package/src/utils/response.tsx +62 -33
- package/src/utils/serve.ts +29 -27
- package/src/utils/ssrHandler.ts +54 -25
- package/src/utils/staticFile.ts +2 -7
package/dist/cli.js
CHANGED
|
@@ -107,7 +107,11 @@ var parseCookies = (cookieString) => {
|
|
|
107
107
|
if (index > -1) {
|
|
108
108
|
const key = pair.slice(0, index).trim();
|
|
109
109
|
const value = pair.slice(index + 1).trim();
|
|
110
|
-
|
|
110
|
+
try {
|
|
111
|
+
cookies[key] = decodeURIComponent(value);
|
|
112
|
+
} catch {
|
|
113
|
+
cookies[key] = value;
|
|
114
|
+
}
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
return cookies;
|
|
@@ -171,6 +175,13 @@ function swapContextMap(map) {
|
|
|
171
175
|
function captureMap() {
|
|
172
176
|
return _g[MAP_KEY];
|
|
173
177
|
}
|
|
178
|
+
var UNSUSPEND_KEY = "__hadarsUnsuspend";
|
|
179
|
+
function captureUnsuspend() {
|
|
180
|
+
return _g[UNSUSPEND_KEY];
|
|
181
|
+
}
|
|
182
|
+
function restoreUnsuspend(u) {
|
|
183
|
+
_g[UNSUSPEND_KEY] = u;
|
|
184
|
+
}
|
|
174
185
|
function getContextValue(context) {
|
|
175
186
|
const map = _g[MAP_KEY];
|
|
176
187
|
if (map && map.has(context)) return map.get(context);
|
|
@@ -178,10 +189,14 @@ function getContextValue(context) {
|
|
|
178
189
|
return "_defaultValue" in c ? c._defaultValue : c._currentValue;
|
|
179
190
|
}
|
|
180
191
|
function pushContextValue(context, value) {
|
|
181
|
-
|
|
192
|
+
let map = _g[MAP_KEY];
|
|
193
|
+
if (map === null) {
|
|
194
|
+
map = /* @__PURE__ */ new Map();
|
|
195
|
+
_g[MAP_KEY] = map;
|
|
196
|
+
}
|
|
182
197
|
const c = context;
|
|
183
|
-
const prev = map
|
|
184
|
-
map
|
|
198
|
+
const prev = map.has(context) ? map.get(context) : "_defaultValue" in c ? c._defaultValue : c._currentValue;
|
|
199
|
+
map.set(context, value);
|
|
185
200
|
return prev;
|
|
186
201
|
}
|
|
187
202
|
function popContextValue(context, prev) {
|
|
@@ -189,48 +204,57 @@ function popContextValue(context, prev) {
|
|
|
189
204
|
}
|
|
190
205
|
var GLOBAL_KEY = "__slimReactRenderState";
|
|
191
206
|
var EMPTY = { id: 1, overflow: "" };
|
|
207
|
+
var _stateCache = null;
|
|
192
208
|
function s() {
|
|
193
|
-
|
|
194
|
-
if (!
|
|
195
|
-
|
|
209
|
+
if (_stateCache !== null) return _stateCache;
|
|
210
|
+
if (!_g[GLOBAL_KEY]) {
|
|
211
|
+
_g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
|
|
196
212
|
}
|
|
197
|
-
|
|
213
|
+
_stateCache = _g[GLOBAL_KEY];
|
|
214
|
+
return _stateCache;
|
|
198
215
|
}
|
|
216
|
+
var _treeIdStack = [];
|
|
217
|
+
var _treeOvStack = [];
|
|
218
|
+
var _treeDepth = 0;
|
|
199
219
|
function resetRenderState(idPrefix = "") {
|
|
200
220
|
const st = s();
|
|
201
|
-
st.currentTreeContext =
|
|
221
|
+
st.currentTreeContext.id = EMPTY.id;
|
|
222
|
+
st.currentTreeContext.overflow = EMPTY.overflow;
|
|
202
223
|
st.localIdCounter = 0;
|
|
203
224
|
st.idPrefix = idPrefix;
|
|
225
|
+
_treeDepth = 0;
|
|
204
226
|
}
|
|
205
227
|
function pushTreeContext(totalChildren, index) {
|
|
206
228
|
const st = s();
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
229
|
+
const ctx = st.currentTreeContext;
|
|
230
|
+
const depth = _treeDepth++;
|
|
231
|
+
_treeIdStack[depth] = ctx.id;
|
|
232
|
+
_treeOvStack[depth] = ctx.overflow;
|
|
233
|
+
const baseIdWithLeadingBit = ctx.id;
|
|
234
|
+
const baseOverflow = ctx.overflow;
|
|
210
235
|
const baseLength = 31 - Math.clz32(baseIdWithLeadingBit);
|
|
211
236
|
let baseId = baseIdWithLeadingBit & ~(1 << baseLength);
|
|
212
237
|
const slot = index + 1;
|
|
213
238
|
const newBits = 32 - Math.clz32(totalChildren);
|
|
214
239
|
const length = newBits + baseLength;
|
|
215
240
|
if (30 < length) {
|
|
216
|
-
const
|
|
217
|
-
const overflowStr = (baseId & (1 <<
|
|
218
|
-
baseId >>=
|
|
219
|
-
const newBaseLength = baseLength -
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
overflow: overflowStr + baseOverflow
|
|
223
|
-
};
|
|
241
|
+
const overflowBits = baseLength - baseLength % 5;
|
|
242
|
+
const overflowStr = (baseId & (1 << overflowBits) - 1).toString(32);
|
|
243
|
+
baseId >>= overflowBits;
|
|
244
|
+
const newBaseLength = baseLength - overflowBits;
|
|
245
|
+
ctx.id = 1 << newBits + newBaseLength | slot << newBaseLength | baseId;
|
|
246
|
+
ctx.overflow = overflowStr + baseOverflow;
|
|
224
247
|
} else {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
overflow: baseOverflow
|
|
228
|
-
};
|
|
248
|
+
ctx.id = 1 << length | slot << baseLength | baseId;
|
|
249
|
+
ctx.overflow = baseOverflow;
|
|
229
250
|
}
|
|
230
|
-
return
|
|
251
|
+
return depth;
|
|
231
252
|
}
|
|
232
|
-
function popTreeContext(
|
|
233
|
-
s().currentTreeContext
|
|
253
|
+
function popTreeContext(depth) {
|
|
254
|
+
const ctx = s().currentTreeContext;
|
|
255
|
+
ctx.id = _treeIdStack[depth];
|
|
256
|
+
ctx.overflow = _treeOvStack[depth];
|
|
257
|
+
_treeDepth = depth;
|
|
234
258
|
}
|
|
235
259
|
function pushComponentScope() {
|
|
236
260
|
const st = s();
|
|
@@ -246,12 +270,16 @@ function componentCalledUseId() {
|
|
|
246
270
|
}
|
|
247
271
|
function snapshotContext() {
|
|
248
272
|
const st = s();
|
|
249
|
-
|
|
273
|
+
const ctx = st.currentTreeContext;
|
|
274
|
+
return { tree: { id: ctx.id, overflow: ctx.overflow }, localId: st.localIdCounter, treeDepth: _treeDepth };
|
|
250
275
|
}
|
|
251
276
|
function restoreContext(snap) {
|
|
252
277
|
const st = s();
|
|
253
|
-
|
|
278
|
+
const ctx = st.currentTreeContext;
|
|
279
|
+
ctx.id = snap.tree.id;
|
|
280
|
+
ctx.overflow = snap.tree.overflow;
|
|
254
281
|
st.localIdCounter = snap.localId;
|
|
282
|
+
_treeDepth = snap.treeDepth;
|
|
255
283
|
}
|
|
256
284
|
function getTreeId() {
|
|
257
285
|
const { id, overflow } = s().currentTreeContext;
|
|
@@ -382,19 +410,80 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
382
410
|
"wbr"
|
|
383
411
|
]);
|
|
384
412
|
var HTML_ESC = { "&": "&", "<": "<", ">": ">", "'": "'" };
|
|
413
|
+
var HTML_ESC_RE = /[&<>']/;
|
|
385
414
|
function escapeHtml(str) {
|
|
415
|
+
if (!HTML_ESC_RE.test(str)) return str;
|
|
386
416
|
return str.replace(/[&<>']/g, (c) => HTML_ESC[c]);
|
|
387
417
|
}
|
|
388
418
|
var ATTR_ESC = { "&": "&", '"': """, "<": "<", ">": ">" };
|
|
419
|
+
var ATTR_ESC_RE = /[&"<>]/;
|
|
389
420
|
function escapeAttr(str) {
|
|
421
|
+
if (!ATTR_ESC_RE.test(str)) return str;
|
|
390
422
|
return str.replace(/[&"<>]/g, (c) => ATTR_ESC[c]);
|
|
391
423
|
}
|
|
424
|
+
var UNITLESS_CSS = /* @__PURE__ */ new Set([
|
|
425
|
+
"animationIterationCount",
|
|
426
|
+
"aspectRatio",
|
|
427
|
+
"borderImageOutset",
|
|
428
|
+
"borderImageSlice",
|
|
429
|
+
"borderImageWidth",
|
|
430
|
+
"boxFlex",
|
|
431
|
+
"boxFlexGroup",
|
|
432
|
+
"boxOrdinalGroup",
|
|
433
|
+
"columnCount",
|
|
434
|
+
"columns",
|
|
435
|
+
"flex",
|
|
436
|
+
"flexGrow",
|
|
437
|
+
"flexPositive",
|
|
438
|
+
"flexShrink",
|
|
439
|
+
"flexNegative",
|
|
440
|
+
"flexOrder",
|
|
441
|
+
"gridArea",
|
|
442
|
+
"gridRow",
|
|
443
|
+
"gridRowEnd",
|
|
444
|
+
"gridRowSpan",
|
|
445
|
+
"gridRowStart",
|
|
446
|
+
"gridColumn",
|
|
447
|
+
"gridColumnEnd",
|
|
448
|
+
"gridColumnSpan",
|
|
449
|
+
"gridColumnStart",
|
|
450
|
+
"fontWeight",
|
|
451
|
+
"lineClamp",
|
|
452
|
+
"lineHeight",
|
|
453
|
+
"opacity",
|
|
454
|
+
"order",
|
|
455
|
+
"orphans",
|
|
456
|
+
"scale",
|
|
457
|
+
"tabSize",
|
|
458
|
+
"widows",
|
|
459
|
+
"zIndex",
|
|
460
|
+
"zoom",
|
|
461
|
+
"fillOpacity",
|
|
462
|
+
"floodOpacity",
|
|
463
|
+
"stopOpacity",
|
|
464
|
+
"strokeDasharray",
|
|
465
|
+
"strokeDashoffset",
|
|
466
|
+
"strokeMiterlimit",
|
|
467
|
+
"strokeOpacity",
|
|
468
|
+
"strokeWidth"
|
|
469
|
+
]);
|
|
470
|
+
var _cssKeyCache = /* @__PURE__ */ new Map();
|
|
392
471
|
function styleObjectToString(style) {
|
|
393
472
|
let result = "";
|
|
394
473
|
for (const key in style) {
|
|
474
|
+
const value = style[key];
|
|
475
|
+
if (value == null || typeof value === "boolean") continue;
|
|
395
476
|
if (result) result += ";";
|
|
396
|
-
|
|
397
|
-
|
|
477
|
+
let cssKey = _cssKeyCache.get(key);
|
|
478
|
+
if (cssKey === void 0) {
|
|
479
|
+
cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
480
|
+
_cssKeyCache.set(key, cssKey);
|
|
481
|
+
}
|
|
482
|
+
if (typeof value === "number" && value !== 0 && !UNITLESS_CSS.has(key)) {
|
|
483
|
+
result += cssKey + ":" + value + "px";
|
|
484
|
+
} else {
|
|
485
|
+
result += cssKey + ":" + value;
|
|
486
|
+
}
|
|
398
487
|
}
|
|
399
488
|
return result;
|
|
400
489
|
}
|
|
@@ -529,14 +618,22 @@ var SVG_ATTR_MAP = {
|
|
|
529
618
|
xChannelSelector: "xChannelSelector",
|
|
530
619
|
yChannelSelector: "yChannelSelector"
|
|
531
620
|
};
|
|
532
|
-
|
|
533
|
-
|
|
621
|
+
var TEXTAREA_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue", "children"]);
|
|
622
|
+
var SELECT_SKIP_PROPS = /* @__PURE__ */ new Set(["value", "defaultValue"]);
|
|
623
|
+
var INTERNAL_PROPS = /* @__PURE__ */ new Set([
|
|
624
|
+
"children",
|
|
625
|
+
"key",
|
|
626
|
+
"ref",
|
|
627
|
+
"dangerouslySetInnerHTML",
|
|
628
|
+
"suppressHydrationWarning",
|
|
629
|
+
"suppressContentEditableWarning"
|
|
630
|
+
]);
|
|
631
|
+
function writeAttributes(writer, props, isSvg, skip) {
|
|
534
632
|
for (const key in props) {
|
|
633
|
+
if (skip !== void 0 && skip.has(key)) continue;
|
|
535
634
|
const value = props[key];
|
|
536
|
-
if (key
|
|
537
|
-
|
|
538
|
-
if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
|
|
539
|
-
continue;
|
|
635
|
+
if (INTERNAL_PROPS.has(key)) continue;
|
|
636
|
+
if (key.length > 2 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90) continue;
|
|
540
637
|
let attrName;
|
|
541
638
|
if (isSvg && key in SVG_ATTR_MAP) {
|
|
542
639
|
attrName = SVG_ATTR_MAP[key];
|
|
@@ -544,41 +641,46 @@ function renderAttributes(props, isSvg) {
|
|
|
544
641
|
attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
|
|
545
642
|
}
|
|
546
643
|
if (value === false || value == null) {
|
|
547
|
-
if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
|
|
548
|
-
|
|
644
|
+
if (value === false && (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-"))) {
|
|
645
|
+
writer.write(` ${attrName}="false"`);
|
|
549
646
|
}
|
|
550
647
|
continue;
|
|
551
648
|
}
|
|
552
649
|
if (value === true) {
|
|
553
|
-
if (attrName.startsWith("aria-") || attrName.startsWith("data-")) {
|
|
554
|
-
|
|
650
|
+
if (attrName.charCodeAt(0) === 97 && attrName.startsWith("aria-") || attrName.charCodeAt(0) === 100 && attrName.startsWith("data-")) {
|
|
651
|
+
writer.write(` ${attrName}="true"`);
|
|
555
652
|
} else {
|
|
556
|
-
|
|
653
|
+
writer.write(` ${attrName}=""`);
|
|
557
654
|
}
|
|
558
655
|
continue;
|
|
559
656
|
}
|
|
560
657
|
if (key === "style" && typeof value === "object") {
|
|
561
658
|
const styleStr = styleObjectToString(value);
|
|
562
|
-
if (styleStr)
|
|
659
|
+
if (styleStr) writer.write(` style="${escapeAttr(styleStr)}"`);
|
|
563
660
|
continue;
|
|
564
661
|
}
|
|
565
|
-
|
|
662
|
+
writer.write(` ${attrName}="${escapeAttr(typeof value === "string" ? value : String(value))}"`);
|
|
566
663
|
}
|
|
567
|
-
return attrs;
|
|
568
664
|
}
|
|
569
|
-
var BufferWriter = class {
|
|
570
|
-
|
|
665
|
+
var BufferWriter = class _BufferWriter {
|
|
666
|
+
data = "";
|
|
571
667
|
lastWasText = false;
|
|
572
668
|
write(chunk) {
|
|
573
|
-
this.
|
|
669
|
+
this.data += chunk;
|
|
574
670
|
this.lastWasText = false;
|
|
575
671
|
}
|
|
576
672
|
text(s2) {
|
|
577
|
-
this.
|
|
673
|
+
this.data += s2;
|
|
578
674
|
this.lastWasText = true;
|
|
579
675
|
}
|
|
580
|
-
|
|
581
|
-
|
|
676
|
+
/** Flush accumulated output into a parent writer and reset. */
|
|
677
|
+
flushTo(target) {
|
|
678
|
+
if (!this.data) return;
|
|
679
|
+
if (target instanceof _BufferWriter) {
|
|
680
|
+
target.data += this.data;
|
|
681
|
+
} else {
|
|
682
|
+
target.write(this.data);
|
|
683
|
+
}
|
|
582
684
|
target.lastWasText = this.lastWasText;
|
|
583
685
|
}
|
|
584
686
|
};
|
|
@@ -595,15 +697,12 @@ function renderNode(node, writer, isSvg = false) {
|
|
|
595
697
|
if (Array.isArray(node)) {
|
|
596
698
|
return renderChildArray(node, writer, isSvg);
|
|
597
699
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
writer,
|
|
602
|
-
isSvg
|
|
603
|
-
);
|
|
700
|
+
const obj = node;
|
|
701
|
+
if (Symbol.iterator in obj && !("$$typeof" in obj)) {
|
|
702
|
+
return renderChildArray(Array.from(obj), writer, isSvg);
|
|
604
703
|
}
|
|
605
|
-
if (
|
|
606
|
-
const elType =
|
|
704
|
+
if ("$$typeof" in obj) {
|
|
705
|
+
const elType = obj["$$typeof"];
|
|
607
706
|
if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT) return;
|
|
608
707
|
const element = node;
|
|
609
708
|
const { type, props } = element;
|
|
@@ -613,15 +712,15 @@ function renderNode(node, writer, isSvg = false) {
|
|
|
613
712
|
if (type === SUSPENSE_TYPE) {
|
|
614
713
|
return renderSuspense(props, writer, isSvg);
|
|
615
714
|
}
|
|
715
|
+
if (typeof type === "string") {
|
|
716
|
+
return renderHostElement(type, props, writer, isSvg);
|
|
717
|
+
}
|
|
616
718
|
if (typeof type === "function") {
|
|
617
719
|
return renderComponent(type, props, writer, isSvg);
|
|
618
720
|
}
|
|
619
721
|
if (typeof type === "object" && type !== null) {
|
|
620
722
|
return renderComponent(type, props, writer, isSvg);
|
|
621
723
|
}
|
|
622
|
-
if (typeof type === "string") {
|
|
623
|
-
return renderHostElement(type, props, writer, isSvg);
|
|
624
|
-
}
|
|
625
724
|
}
|
|
626
725
|
}
|
|
627
726
|
function markSelectedOptionsMulti(children, selectedValues) {
|
|
@@ -647,26 +746,21 @@ function markSelectedOptionsMulti(children, selectedValues) {
|
|
|
647
746
|
return children;
|
|
648
747
|
}
|
|
649
748
|
function renderHostElement(tag, props, writer, isSvg) {
|
|
650
|
-
const
|
|
651
|
-
const childSvg = isSvg || enteringSvg;
|
|
749
|
+
const childSvg = isSvg || tag === "svg";
|
|
652
750
|
if (tag === "textarea") {
|
|
653
751
|
const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
|
|
752
|
+
writer.write("<textarea");
|
|
753
|
+
writeAttributes(writer, props, false, TEXTAREA_SKIP_PROPS);
|
|
754
|
+
writer.write(">");
|
|
659
755
|
writer.text(escapeHtml(String(textContent)));
|
|
660
756
|
writer.write("</textarea>");
|
|
661
757
|
return;
|
|
662
758
|
}
|
|
663
759
|
if (tag === "select") {
|
|
664
760
|
const selectedValue = props.value ?? props.defaultValue;
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
}
|
|
669
|
-
writer.write(`<select${renderAttributes(filteredProps, false)}>`);
|
|
761
|
+
writer.write("<select");
|
|
762
|
+
writeAttributes(writer, props, false, SELECT_SKIP_PROPS);
|
|
763
|
+
writer.write(">");
|
|
670
764
|
const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
|
|
671
765
|
const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
|
|
672
766
|
const inner2 = renderChildren(patchedChildren, writer, false);
|
|
@@ -678,7 +772,8 @@ function renderHostElement(tag, props, writer, isSvg) {
|
|
|
678
772
|
writer.write("</select>");
|
|
679
773
|
return;
|
|
680
774
|
}
|
|
681
|
-
writer.write(`<${tag}
|
|
775
|
+
writer.write(`<${tag}`);
|
|
776
|
+
writeAttributes(writer, props, childSvg);
|
|
682
777
|
if (VOID_ELEMENTS.has(tag)) {
|
|
683
778
|
writer.write("/>");
|
|
684
779
|
return;
|
|
@@ -704,8 +799,25 @@ var REACT_PROVIDER = /* @__PURE__ */ Symbol.for("react.provider");
|
|
|
704
799
|
var REACT_CONTEXT = /* @__PURE__ */ Symbol.for("react.context");
|
|
705
800
|
var REACT_CONSUMER = /* @__PURE__ */ Symbol.for("react.consumer");
|
|
706
801
|
var REACT_LAZY = /* @__PURE__ */ Symbol.for("react.lazy");
|
|
707
|
-
|
|
708
|
-
|
|
802
|
+
var SUSPENSE_RETRY_LIMIT = /* @__PURE__ */ Symbol("SuspenseRetryLimit");
|
|
803
|
+
var MAX_COMPONENT_SUSPENSE_RETRIES = 25;
|
|
804
|
+
function patchPromiseStatus(p) {
|
|
805
|
+
const w = p;
|
|
806
|
+
if (w.status) return;
|
|
807
|
+
w.status = "pending";
|
|
808
|
+
w.then(
|
|
809
|
+
(v) => {
|
|
810
|
+
w.status = "fulfilled";
|
|
811
|
+
w.value = v;
|
|
812
|
+
},
|
|
813
|
+
(r) => {
|
|
814
|
+
w.status = "rejected";
|
|
815
|
+
w.reason = r;
|
|
816
|
+
}
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
820
|
+
const typeOf = type.$$typeof;
|
|
709
821
|
if (typeOf === REACT_MEMO) {
|
|
710
822
|
return renderNode(
|
|
711
823
|
{ $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
|
|
@@ -717,7 +829,23 @@ function renderComponent(type, props, writer, isSvg) {
|
|
|
717
829
|
return renderComponent(type.render, props, writer, isSvg);
|
|
718
830
|
}
|
|
719
831
|
if (typeOf === REACT_LAZY) {
|
|
720
|
-
|
|
832
|
+
let resolved;
|
|
833
|
+
try {
|
|
834
|
+
resolved = type._init(type._payload);
|
|
835
|
+
} catch (e) {
|
|
836
|
+
if (e && typeof e.then === "function") {
|
|
837
|
+
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
838
|
+
patchPromiseStatus(e);
|
|
839
|
+
const m = captureMap();
|
|
840
|
+
const u = captureUnsuspend();
|
|
841
|
+
return e.then(() => {
|
|
842
|
+
swapContextMap(m);
|
|
843
|
+
restoreUnsuspend(u);
|
|
844
|
+
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
throw e;
|
|
848
|
+
}
|
|
721
849
|
const LazyComp = resolved?.default ?? resolved;
|
|
722
850
|
return renderComponent(LazyComp, props, writer, isSvg);
|
|
723
851
|
}
|
|
@@ -726,12 +854,12 @@ function renderComponent(type, props, writer, isSvg) {
|
|
|
726
854
|
const value = ctx2 ? getContextValue(ctx2) : void 0;
|
|
727
855
|
const result2 = typeof props.children === "function" ? props.children(value) : null;
|
|
728
856
|
const savedScope2 = pushComponentScope();
|
|
729
|
-
const
|
|
857
|
+
const finish = () => popComponentScope(savedScope2);
|
|
730
858
|
const r2 = renderNode(result2, writer, isSvg);
|
|
731
859
|
if (r2 && typeof r2.then === "function") {
|
|
732
|
-
return r2.then(
|
|
860
|
+
return r2.then(finish);
|
|
733
861
|
}
|
|
734
|
-
|
|
862
|
+
finish();
|
|
735
863
|
return;
|
|
736
864
|
}
|
|
737
865
|
const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
|
|
@@ -743,26 +871,29 @@ function renderComponent(type, props, writer, isSvg) {
|
|
|
743
871
|
}
|
|
744
872
|
const savedScope = pushComponentScope();
|
|
745
873
|
if (isProvider && typeof type !== "function") {
|
|
746
|
-
const
|
|
874
|
+
const finish = () => {
|
|
747
875
|
popComponentScope(savedScope);
|
|
748
876
|
popContextValue(ctx, prevCtxValue);
|
|
749
877
|
};
|
|
750
878
|
const r2 = renderChildren(props.children, writer, isSvg);
|
|
751
879
|
if (r2 && typeof r2.then === "function") {
|
|
752
880
|
const m = captureMap();
|
|
881
|
+
const u = captureUnsuspend();
|
|
753
882
|
return r2.then(
|
|
754
883
|
() => {
|
|
755
884
|
swapContextMap(m);
|
|
756
|
-
|
|
885
|
+
restoreUnsuspend(u);
|
|
886
|
+
finish();
|
|
757
887
|
},
|
|
758
888
|
(e) => {
|
|
759
889
|
swapContextMap(m);
|
|
760
|
-
|
|
890
|
+
restoreUnsuspend(u);
|
|
891
|
+
finish();
|
|
761
892
|
throw e;
|
|
762
893
|
}
|
|
763
894
|
);
|
|
764
895
|
}
|
|
765
|
-
|
|
896
|
+
finish();
|
|
766
897
|
return;
|
|
767
898
|
}
|
|
768
899
|
let result;
|
|
@@ -782,6 +913,17 @@ function renderComponent(type, props, writer, isSvg) {
|
|
|
782
913
|
restoreDispatcher(prevDispatcher);
|
|
783
914
|
popComponentScope(savedScope);
|
|
784
915
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
916
|
+
if (e && typeof e.then === "function") {
|
|
917
|
+
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
918
|
+
patchPromiseStatus(e);
|
|
919
|
+
const m = captureMap();
|
|
920
|
+
const u = captureUnsuspend();
|
|
921
|
+
return e.then(() => {
|
|
922
|
+
swapContextMap(m);
|
|
923
|
+
restoreUnsuspend(u);
|
|
924
|
+
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
925
|
+
});
|
|
926
|
+
}
|
|
785
927
|
throw e;
|
|
786
928
|
}
|
|
787
929
|
restoreDispatcher(prevDispatcher);
|
|
@@ -789,97 +931,93 @@ function renderComponent(type, props, writer, isSvg) {
|
|
|
789
931
|
if (!(result instanceof Promise) && componentCalledUseId()) {
|
|
790
932
|
savedIdTree = pushTreeContext(1, 0);
|
|
791
933
|
}
|
|
792
|
-
const finish = () => {
|
|
793
|
-
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
794
|
-
popComponentScope(savedScope);
|
|
795
|
-
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
796
|
-
};
|
|
797
934
|
if (result instanceof Promise) {
|
|
798
935
|
const m = captureMap();
|
|
936
|
+
const u = captureUnsuspend();
|
|
799
937
|
return result.then((resolved) => {
|
|
800
938
|
swapContextMap(m);
|
|
939
|
+
restoreUnsuspend(u);
|
|
801
940
|
let asyncSavedIdTree;
|
|
802
941
|
if (componentCalledUseId()) {
|
|
803
942
|
asyncSavedIdTree = pushTreeContext(1, 0);
|
|
804
943
|
}
|
|
805
|
-
const asyncFinish = () => {
|
|
806
|
-
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
807
|
-
popComponentScope(savedScope);
|
|
808
|
-
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
809
|
-
};
|
|
810
944
|
const r2 = renderNode(resolved, writer, isSvg);
|
|
811
945
|
if (r2 && typeof r2.then === "function") {
|
|
812
946
|
const m2 = captureMap();
|
|
947
|
+
const u2 = captureUnsuspend();
|
|
813
948
|
return r2.then(
|
|
814
949
|
() => {
|
|
815
950
|
swapContextMap(m2);
|
|
816
|
-
|
|
951
|
+
restoreUnsuspend(u2);
|
|
952
|
+
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
953
|
+
popComponentScope(savedScope);
|
|
954
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
817
955
|
},
|
|
818
956
|
(e) => {
|
|
819
957
|
swapContextMap(m2);
|
|
820
|
-
|
|
958
|
+
restoreUnsuspend(u2);
|
|
959
|
+
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
960
|
+
popComponentScope(savedScope);
|
|
961
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
821
962
|
throw e;
|
|
822
963
|
}
|
|
823
964
|
);
|
|
824
965
|
}
|
|
825
|
-
|
|
966
|
+
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
967
|
+
popComponentScope(savedScope);
|
|
968
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
826
969
|
}, (e) => {
|
|
827
970
|
swapContextMap(m);
|
|
828
|
-
|
|
971
|
+
restoreUnsuspend(u);
|
|
972
|
+
popComponentScope(savedScope);
|
|
973
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
829
974
|
throw e;
|
|
830
975
|
});
|
|
831
976
|
}
|
|
832
977
|
const r = renderNode(result, writer, isSvg);
|
|
833
978
|
if (r && typeof r.then === "function") {
|
|
834
979
|
const m = captureMap();
|
|
980
|
+
const u = captureUnsuspend();
|
|
835
981
|
return r.then(
|
|
836
982
|
() => {
|
|
837
983
|
swapContextMap(m);
|
|
838
|
-
|
|
984
|
+
restoreUnsuspend(u);
|
|
985
|
+
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
986
|
+
popComponentScope(savedScope);
|
|
987
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
839
988
|
},
|
|
840
989
|
(e) => {
|
|
841
990
|
swapContextMap(m);
|
|
842
|
-
|
|
991
|
+
restoreUnsuspend(u);
|
|
992
|
+
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
993
|
+
popComponentScope(savedScope);
|
|
994
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
843
995
|
throw e;
|
|
844
996
|
}
|
|
845
997
|
);
|
|
846
998
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
return typeof node === "string" || typeof node === "number";
|
|
999
|
+
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
1000
|
+
popComponentScope(savedScope);
|
|
1001
|
+
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
851
1002
|
}
|
|
852
1003
|
function renderChildArray(children, writer, isSvg) {
|
|
853
|
-
|
|
854
|
-
for (let i = 0; i < totalChildren; i++) {
|
|
855
|
-
if (isTextLike(children[i]) && writer.lastWasText) {
|
|
856
|
-
writer.write("<!-- -->");
|
|
857
|
-
}
|
|
858
|
-
const savedTree = pushTreeContext(totalChildren, i);
|
|
859
|
-
const r = renderNode(children[i], writer, isSvg);
|
|
860
|
-
if (r && typeof r.then === "function") {
|
|
861
|
-
const m = captureMap();
|
|
862
|
-
return r.then(() => {
|
|
863
|
-
swapContextMap(m);
|
|
864
|
-
popTreeContext(savedTree);
|
|
865
|
-
return renderChildArrayFrom(children, i + 1, writer, isSvg);
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
popTreeContext(savedTree);
|
|
869
|
-
}
|
|
1004
|
+
return renderChildArrayFrom(children, 0, writer, isSvg);
|
|
870
1005
|
}
|
|
871
1006
|
function renderChildArrayFrom(children, startIndex, writer, isSvg) {
|
|
872
1007
|
const totalChildren = children.length;
|
|
873
1008
|
for (let i = startIndex; i < totalChildren; i++) {
|
|
874
|
-
|
|
1009
|
+
const child = children[i];
|
|
1010
|
+
if ((typeof child === "string" || typeof child === "number") && writer.lastWasText) {
|
|
875
1011
|
writer.write("<!-- -->");
|
|
876
1012
|
}
|
|
877
1013
|
const savedTree = pushTreeContext(totalChildren, i);
|
|
878
|
-
const r = renderNode(
|
|
1014
|
+
const r = renderNode(child, writer, isSvg);
|
|
879
1015
|
if (r && typeof r.then === "function") {
|
|
880
1016
|
const m = captureMap();
|
|
1017
|
+
const u = captureUnsuspend();
|
|
881
1018
|
return r.then(() => {
|
|
882
1019
|
swapContextMap(m);
|
|
1020
|
+
restoreUnsuspend(u);
|
|
883
1021
|
popTreeContext(savedTree);
|
|
884
1022
|
return renderChildArrayFrom(children, i + 1, writer, isSvg);
|
|
885
1023
|
});
|
|
@@ -894,87 +1032,94 @@ function renderChildren(children, writer, isSvg = false) {
|
|
|
894
1032
|
}
|
|
895
1033
|
return renderNode(children, writer, isSvg);
|
|
896
1034
|
}
|
|
897
|
-
var MAX_SUSPENSE_RETRIES = 25;
|
|
898
1035
|
async function renderSuspense(props, writer, isSvg = false) {
|
|
899
1036
|
const { children, fallback } = props;
|
|
900
|
-
let attempts = 0;
|
|
901
1037
|
const snap = snapshotContext();
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1038
|
+
const savedMap = captureMap();
|
|
1039
|
+
const savedMapClone = savedMap ? new Map(savedMap) : null;
|
|
1040
|
+
const buffer = new BufferWriter();
|
|
1041
|
+
try {
|
|
1042
|
+
const r = renderNode(children, buffer, isSvg);
|
|
1043
|
+
if (r && typeof r.then === "function") {
|
|
1044
|
+
const m = captureMap();
|
|
1045
|
+
const u = captureUnsuspend();
|
|
1046
|
+
await r;
|
|
1047
|
+
swapContextMap(m);
|
|
1048
|
+
restoreUnsuspend(u);
|
|
1049
|
+
}
|
|
1050
|
+
writer.write("<!--$-->");
|
|
1051
|
+
buffer.flushTo(writer);
|
|
1052
|
+
writer.write("<!--/$-->");
|
|
1053
|
+
writer.flush?.();
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
if (error === SUSPENSE_RETRY_LIMIT) {
|
|
1056
|
+
restoreContext(snap);
|
|
1057
|
+
swapContextMap(savedMapClone);
|
|
1058
|
+
writer.write("<!--$?-->");
|
|
1059
|
+
if (fallback) {
|
|
1060
|
+
const r = renderNode(fallback, writer, isSvg);
|
|
1061
|
+
if (r && typeof r.then === "function") {
|
|
1062
|
+
const m = captureMap();
|
|
1063
|
+
const u = captureUnsuspend();
|
|
1064
|
+
await r;
|
|
1065
|
+
swapContextMap(m);
|
|
1066
|
+
restoreUnsuspend(u);
|
|
1067
|
+
}
|
|
911
1068
|
}
|
|
912
|
-
writer.write("<!--$-->");
|
|
913
|
-
buffer.flush(writer);
|
|
914
1069
|
writer.write("<!--/$-->");
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (error && typeof error.then === "function") {
|
|
918
|
-
const m = captureMap();
|
|
919
|
-
await error;
|
|
920
|
-
swapContextMap(m);
|
|
921
|
-
attempts++;
|
|
922
|
-
} else {
|
|
923
|
-
throw error;
|
|
924
|
-
}
|
|
1070
|
+
} else {
|
|
1071
|
+
throw error;
|
|
925
1072
|
}
|
|
926
1073
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1074
|
+
}
|
|
1075
|
+
var _streamEncoder = new TextEncoder();
|
|
1076
|
+
var NULL_WRITER = {
|
|
1077
|
+
lastWasText: false,
|
|
1078
|
+
write(_c) {
|
|
1079
|
+
},
|
|
1080
|
+
text(_s) {
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
async function renderPreflight(element, options) {
|
|
1084
|
+
const idPrefix = options?.identifierPrefix ?? "";
|
|
1085
|
+
const prev = swapContextMap(null);
|
|
1086
|
+
try {
|
|
1087
|
+
resetRenderState(idPrefix);
|
|
1088
|
+
NULL_WRITER.lastWasText = false;
|
|
1089
|
+
const r = renderNode(element, NULL_WRITER);
|
|
931
1090
|
if (r && typeof r.then === "function") {
|
|
932
1091
|
const m = captureMap();
|
|
933
1092
|
await r;
|
|
934
1093
|
swapContextMap(m);
|
|
935
1094
|
}
|
|
1095
|
+
} finally {
|
|
1096
|
+
swapContextMap(prev);
|
|
936
1097
|
}
|
|
937
|
-
writer.write("<!--/$-->");
|
|
938
1098
|
}
|
|
939
1099
|
async function renderToString(element, options) {
|
|
940
1100
|
const idPrefix = options?.identifierPrefix ?? "";
|
|
941
|
-
const
|
|
942
|
-
|
|
1101
|
+
const prev = swapContextMap(null);
|
|
1102
|
+
let output = "";
|
|
1103
|
+
const writer = {
|
|
1104
|
+
lastWasText: false,
|
|
1105
|
+
write(c) {
|
|
1106
|
+
output += c;
|
|
1107
|
+
this.lastWasText = false;
|
|
1108
|
+
},
|
|
1109
|
+
text(s2) {
|
|
1110
|
+
output += s2;
|
|
1111
|
+
this.lastWasText = true;
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
943
1114
|
try {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
const
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
write(c) {
|
|
951
|
-
chunks.push(c);
|
|
952
|
-
this.lastWasText = false;
|
|
953
|
-
},
|
|
954
|
-
text(s2) {
|
|
955
|
-
chunks.push(s2);
|
|
956
|
-
this.lastWasText = true;
|
|
957
|
-
}
|
|
958
|
-
};
|
|
959
|
-
try {
|
|
960
|
-
const r = renderNode(element, writer);
|
|
961
|
-
if (r && typeof r.then === "function") {
|
|
962
|
-
const m = captureMap();
|
|
963
|
-
await r;
|
|
964
|
-
swapContextMap(m);
|
|
965
|
-
}
|
|
966
|
-
return chunks.join("");
|
|
967
|
-
} catch (error) {
|
|
968
|
-
if (error && typeof error.then === "function") {
|
|
969
|
-
const m = captureMap();
|
|
970
|
-
await error;
|
|
971
|
-
swapContextMap(m);
|
|
972
|
-
continue;
|
|
973
|
-
}
|
|
974
|
-
throw error;
|
|
975
|
-
}
|
|
1115
|
+
resetRenderState(idPrefix);
|
|
1116
|
+
const r = renderNode(element, writer);
|
|
1117
|
+
if (r && typeof r.then === "function") {
|
|
1118
|
+
const m = captureMap();
|
|
1119
|
+
await r;
|
|
1120
|
+
swapContextMap(m);
|
|
976
1121
|
}
|
|
977
|
-
|
|
1122
|
+
return output;
|
|
978
1123
|
} finally {
|
|
979
1124
|
swapContextMap(prev);
|
|
980
1125
|
}
|
|
@@ -995,8 +1140,8 @@ var ATTR = {
|
|
|
995
1140
|
fetchPriority: "fetchpriority",
|
|
996
1141
|
hrefLang: "hreflang"
|
|
997
1142
|
};
|
|
998
|
-
function renderHeadTag(tag, opts, selfClose = false) {
|
|
999
|
-
let attrs = ""
|
|
1143
|
+
function renderHeadTag(tag, id, opts, selfClose = false) {
|
|
1144
|
+
let attrs = ` id="${escAttr(id)}"`;
|
|
1000
1145
|
let inner = "";
|
|
1001
1146
|
for (const [k, v] of Object.entries(opts)) {
|
|
1002
1147
|
if (k === "key" || k === "children") continue;
|
|
@@ -1010,18 +1155,18 @@ function renderHeadTag(tag, opts, selfClose = false) {
|
|
|
1010
1155
|
}
|
|
1011
1156
|
return selfClose ? `<${tag}${attrs}>` : `<${tag}${attrs}>${inner}</${tag}>`;
|
|
1012
1157
|
}
|
|
1013
|
-
|
|
1158
|
+
function buildHeadHtml(seoData) {
|
|
1014
1159
|
let html = `<title>${escText(seoData.title ?? "")}</title>`;
|
|
1015
|
-
for (const opts of Object.
|
|
1016
|
-
html += renderHeadTag("meta", opts, true);
|
|
1017
|
-
for (const opts of Object.
|
|
1018
|
-
html += renderHeadTag("link", opts, true);
|
|
1019
|
-
for (const opts of Object.
|
|
1020
|
-
html += renderHeadTag("style", opts);
|
|
1021
|
-
for (const opts of Object.
|
|
1022
|
-
html += renderHeadTag("script", opts);
|
|
1160
|
+
for (const [id, opts] of Object.entries(seoData.meta))
|
|
1161
|
+
html += renderHeadTag("meta", id, opts, true);
|
|
1162
|
+
for (const [id, opts] of Object.entries(seoData.link))
|
|
1163
|
+
html += renderHeadTag("link", id, opts, true);
|
|
1164
|
+
for (const [id, opts] of Object.entries(seoData.style))
|
|
1165
|
+
html += renderHeadTag("style", id, opts);
|
|
1166
|
+
for (const [id, opts] of Object.entries(seoData.script))
|
|
1167
|
+
html += renderHeadTag("script", id, opts);
|
|
1023
1168
|
return html;
|
|
1024
|
-
}
|
|
1169
|
+
}
|
|
1025
1170
|
var getReactResponse = async (req, opts) => {
|
|
1026
1171
|
const App = opts.document.body;
|
|
1027
1172
|
const { getInitProps, getFinalProps } = opts.document;
|
|
@@ -1035,28 +1180,40 @@ var getReactResponse = async (req, opts) => {
|
|
|
1035
1180
|
};
|
|
1036
1181
|
const unsuspend = { cache: /* @__PURE__ */ new Map() };
|
|
1037
1182
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1038
|
-
|
|
1183
|
+
const element = createElement(App, props);
|
|
1039
1184
|
try {
|
|
1040
|
-
|
|
1185
|
+
await renderPreflight(element);
|
|
1041
1186
|
} finally {
|
|
1042
1187
|
globalThis.__hadarsUnsuspend = null;
|
|
1043
1188
|
}
|
|
1044
|
-
const
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
...Object.keys(serverData).length > 0 ? { __serverData: serverData } : {}
|
|
1189
|
+
const status = context.head.status;
|
|
1190
|
+
const getAppBody = async () => {
|
|
1191
|
+
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1192
|
+
try {
|
|
1193
|
+
return await renderToString(element);
|
|
1194
|
+
} finally {
|
|
1195
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1196
|
+
}
|
|
1053
1197
|
};
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1198
|
+
const finalize = async () => {
|
|
1199
|
+
const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
|
|
1200
|
+
const serverData = {};
|
|
1201
|
+
let hasServerData = false;
|
|
1202
|
+
for (const [key, entry] of unsuspend.cache) {
|
|
1203
|
+
if (entry.status === "fulfilled") {
|
|
1204
|
+
serverData[key] = entry.value;
|
|
1205
|
+
hasServerData = true;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return {
|
|
1209
|
+
clientProps: {
|
|
1210
|
+
...restProps,
|
|
1211
|
+
location: req.location,
|
|
1212
|
+
...hasServerData ? { __serverData: serverData } : {}
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1059
1215
|
};
|
|
1216
|
+
return { head: context.head, status, getAppBody, finalize };
|
|
1060
1217
|
};
|
|
1061
1218
|
|
|
1062
1219
|
// src/utils/rspack.ts
|
|
@@ -1454,27 +1611,6 @@ function nodeReadableToWebStream(readable) {
|
|
|
1454
1611
|
});
|
|
1455
1612
|
}
|
|
1456
1613
|
var noopCtx = { upgrade: () => false };
|
|
1457
|
-
var COMPRESSIBLE_RE = /\b(?:text\/|application\/(?:json|javascript|xml)|image\/svg\+xml)/;
|
|
1458
|
-
function withCompression(handler) {
|
|
1459
|
-
return async (req, ctx) => {
|
|
1460
|
-
const res = await handler(req, ctx);
|
|
1461
|
-
if (!res?.body) return res;
|
|
1462
|
-
if (!COMPRESSIBLE_RE.test(res.headers.get("Content-Type") ?? "")) return res;
|
|
1463
|
-
if (res.headers.has("Content-Encoding")) return res;
|
|
1464
|
-
const accept = req.headers.get("Accept-Encoding") ?? "";
|
|
1465
|
-
const encoding = accept.includes("br") ? "br" : accept.includes("gzip") ? "gzip" : null;
|
|
1466
|
-
if (!encoding) return res;
|
|
1467
|
-
try {
|
|
1468
|
-
const compressed = res.body.pipeThrough(new globalThis.CompressionStream(encoding));
|
|
1469
|
-
const headers = new Headers(res.headers);
|
|
1470
|
-
headers.set("Content-Encoding", encoding);
|
|
1471
|
-
headers.delete("Content-Length");
|
|
1472
|
-
return new Response(compressed, { status: res.status, statusText: res.statusText, headers });
|
|
1473
|
-
} catch {
|
|
1474
|
-
return res;
|
|
1475
|
-
}
|
|
1476
|
-
};
|
|
1477
|
-
}
|
|
1478
1614
|
function withRequestLogging(handler) {
|
|
1479
1615
|
return async (req, ctx) => {
|
|
1480
1616
|
const start = performance.now();
|
|
@@ -1486,9 +1622,27 @@ function withRequestLogging(handler) {
|
|
|
1486
1622
|
return res;
|
|
1487
1623
|
};
|
|
1488
1624
|
}
|
|
1625
|
+
var COMPRESSIBLE_RE = /^text\/|\/json|\/javascript|\/xml|\/wasm/;
|
|
1626
|
+
function withCompression(handler) {
|
|
1627
|
+
return async (req, ctx) => {
|
|
1628
|
+
const res = await handler(req, ctx);
|
|
1629
|
+
if (!res || !res.body) return res;
|
|
1630
|
+
const accept = req.headers.get("Accept-Encoding") ?? "";
|
|
1631
|
+
if (!accept.includes("gzip")) return res;
|
|
1632
|
+
if (res.headers.has("content-encoding")) return res;
|
|
1633
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
1634
|
+
if (!COMPRESSIBLE_RE.test(ct)) return res;
|
|
1635
|
+
const compressed = res.body.pipeThrough(
|
|
1636
|
+
new globalThis.CompressionStream("gzip")
|
|
1637
|
+
);
|
|
1638
|
+
const headers = new Headers(res.headers);
|
|
1639
|
+
headers.set("content-encoding", "gzip");
|
|
1640
|
+
headers.delete("content-length");
|
|
1641
|
+
return new Response(compressed, { status: res.status, headers });
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1489
1644
|
async function serve(port, fetchHandler, websocket) {
|
|
1490
|
-
fetchHandler = withCompression(fetchHandler);
|
|
1491
|
-
fetchHandler = withRequestLogging(fetchHandler);
|
|
1645
|
+
fetchHandler = withCompression(withRequestLogging(fetchHandler));
|
|
1492
1646
|
if (isBun) {
|
|
1493
1647
|
globalThis.Bun.serve({
|
|
1494
1648
|
port,
|
|
@@ -1561,7 +1715,7 @@ async function serve(port, fetchHandler, websocket) {
|
|
|
1561
1715
|
}
|
|
1562
1716
|
|
|
1563
1717
|
// src/utils/staticFile.ts
|
|
1564
|
-
import { readFile
|
|
1718
|
+
import { readFile } from "node:fs/promises";
|
|
1565
1719
|
var MIME = {
|
|
1566
1720
|
html: "text/html; charset=utf-8",
|
|
1567
1721
|
htm: "text/html; charset=utf-8",
|
|
@@ -1587,16 +1741,11 @@ var MIME = {
|
|
|
1587
1741
|
pdf: "application/pdf"
|
|
1588
1742
|
};
|
|
1589
1743
|
async function tryServeFile(filePath) {
|
|
1590
|
-
try {
|
|
1591
|
-
await stat(filePath);
|
|
1592
|
-
} catch {
|
|
1593
|
-
return null;
|
|
1594
|
-
}
|
|
1595
1744
|
try {
|
|
1596
1745
|
const data = await readFile(filePath);
|
|
1597
1746
|
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
|
|
1598
1747
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
1599
|
-
return new Response(data
|
|
1748
|
+
return new Response(data, { headers: { "Content-Type": contentType } });
|
|
1600
1749
|
} catch {
|
|
1601
1750
|
return null;
|
|
1602
1751
|
}
|
|
@@ -1617,16 +1766,25 @@ import cluster from "node:cluster";
|
|
|
1617
1766
|
var HEAD_MARKER = '<meta name="HADARS_HEAD">';
|
|
1618
1767
|
var BODY_MARKER = '<meta name="HADARS_BODY">';
|
|
1619
1768
|
var encoder = new TextEncoder();
|
|
1620
|
-
|
|
1769
|
+
function buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml) {
|
|
1770
|
+
const headHtml = buildHeadHtml(head);
|
|
1771
|
+
const precontentResult = getPrecontentHtml(headHtml);
|
|
1621
1772
|
const responseStream = new ReadableStream({
|
|
1622
1773
|
async start(controller) {
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
`<div id="app">${bodyHtml}</div
|
|
1628
|
-
|
|
1629
|
-
|
|
1774
|
+
try {
|
|
1775
|
+
const [precontentHtml, postContent] = precontentResult instanceof Promise ? await precontentResult : precontentResult;
|
|
1776
|
+
controller.enqueue(encoder.encode(precontentHtml));
|
|
1777
|
+
const bodyHtml = await getAppBody();
|
|
1778
|
+
controller.enqueue(encoder.encode(`<div id="app">${bodyHtml}</div>`));
|
|
1779
|
+
const { clientProps } = await finalize();
|
|
1780
|
+
const scriptContent = JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c");
|
|
1781
|
+
controller.enqueue(encoder.encode(
|
|
1782
|
+
`<script id="hadars" type="application/json">${scriptContent}</script>` + postContent
|
|
1783
|
+
));
|
|
1784
|
+
controller.close();
|
|
1785
|
+
} catch (err) {
|
|
1786
|
+
controller.error(err);
|
|
1787
|
+
}
|
|
1630
1788
|
}
|
|
1631
1789
|
});
|
|
1632
1790
|
return new Response(responseStream, {
|
|
@@ -1638,16 +1796,18 @@ var makePrecontentHtmlGetter = (htmlFilePromise) => {
|
|
|
1638
1796
|
let preHead = null;
|
|
1639
1797
|
let postHead = null;
|
|
1640
1798
|
let postContent = null;
|
|
1641
|
-
return
|
|
1642
|
-
if (preHead
|
|
1643
|
-
|
|
1799
|
+
return (headHtml) => {
|
|
1800
|
+
if (preHead !== null) {
|
|
1801
|
+
return [preHead + headHtml + postHead, postContent];
|
|
1802
|
+
}
|
|
1803
|
+
return htmlFilePromise.then((html) => {
|
|
1644
1804
|
const headEnd = html.indexOf(HEAD_MARKER);
|
|
1645
1805
|
const contentStart = html.indexOf(BODY_MARKER);
|
|
1646
1806
|
preHead = html.slice(0, headEnd);
|
|
1647
1807
|
postHead = html.slice(headEnd + HEAD_MARKER.length, contentStart);
|
|
1648
1808
|
postContent = html.slice(contentStart + BODY_MARKER.length);
|
|
1649
|
-
|
|
1650
|
-
|
|
1809
|
+
return [preHead + headHtml + postHead, postContent];
|
|
1810
|
+
});
|
|
1651
1811
|
};
|
|
1652
1812
|
};
|
|
1653
1813
|
async function transformStream(data, stream) {
|
|
@@ -2117,7 +2277,7 @@ var dev = async (options) => {
|
|
|
2117
2277
|
getInitProps,
|
|
2118
2278
|
getFinalProps
|
|
2119
2279
|
} = await import(importPath);
|
|
2120
|
-
const {
|
|
2280
|
+
const { head, status, getAppBody, finalize } = await getReactResponse(request, {
|
|
2121
2281
|
document: {
|
|
2122
2282
|
body: Component,
|
|
2123
2283
|
lang: "en",
|
|
@@ -2126,13 +2286,14 @@ var dev = async (options) => {
|
|
|
2126
2286
|
}
|
|
2127
2287
|
});
|
|
2128
2288
|
if (request.headers.get("Accept") === "application/json") {
|
|
2289
|
+
const { clientProps } = await finalize();
|
|
2129
2290
|
const serverData = clientProps.__serverData ?? {};
|
|
2130
2291
|
return new Response(JSON.stringify({ serverData }), {
|
|
2131
2292
|
status,
|
|
2132
2293
|
headers: { "Content-Type": "application/json; charset=utf-8" }
|
|
2133
2294
|
});
|
|
2134
2295
|
}
|
|
2135
|
-
return buildSsrResponse(
|
|
2296
|
+
return buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml);
|
|
2136
2297
|
} catch (err) {
|
|
2137
2298
|
console.error("[hadars] SSR render error:", err);
|
|
2138
2299
|
const msg = (err?.stack ?? err?.message ?? String(err)).replace(/</g, "<");
|
|
@@ -2274,7 +2435,7 @@ var run = async (options) => {
|
|
|
2274
2435
|
status: wStatus
|
|
2275
2436
|
});
|
|
2276
2437
|
}
|
|
2277
|
-
const {
|
|
2438
|
+
const { head, status, getAppBody, finalize } = await getReactResponse(request, {
|
|
2278
2439
|
document: {
|
|
2279
2440
|
body: Component,
|
|
2280
2441
|
lang: "en",
|
|
@@ -2283,13 +2444,14 @@ var run = async (options) => {
|
|
|
2283
2444
|
}
|
|
2284
2445
|
});
|
|
2285
2446
|
if (request.headers.get("Accept") === "application/json") {
|
|
2447
|
+
const { clientProps } = await finalize();
|
|
2286
2448
|
const serverData = clientProps.__serverData ?? {};
|
|
2287
2449
|
return new Response(JSON.stringify({ serverData }), {
|
|
2288
2450
|
status,
|
|
2289
2451
|
headers: { "Content-Type": "application/json; charset=utf-8" }
|
|
2290
2452
|
});
|
|
2291
2453
|
}
|
|
2292
|
-
return buildSsrResponse(
|
|
2454
|
+
return buildSsrResponse(head, status, getAppBody, finalize, getPrecontentHtml);
|
|
2293
2455
|
} catch (err) {
|
|
2294
2456
|
console.error("[hadars] SSR render error:", err);
|
|
2295
2457
|
return new Response("Internal Server Error", { status: 500 });
|