hadars 0.1.16 → 0.1.18

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/cli.js CHANGED
@@ -134,24 +134,509 @@ var upgradeHandler = (options) => {
134
134
  return null;
135
135
  };
136
136
 
137
- // src/utils/response.tsx
138
- import { createRequire } from "node:module";
139
- import pathMod from "node:path";
140
- import { pathToFileURL } from "node:url";
141
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
142
- var _renderToStaticMarkup = null;
143
- async function getStaticMarkupRenderer() {
144
- if (!_renderToStaticMarkup) {
145
- const req = createRequire(pathMod.resolve(process.cwd(), "__hadars_fake__.js"));
146
- const resolved = req.resolve("react-dom/server");
147
- const mod = await import(pathToFileURL(resolved).href);
148
- _renderToStaticMarkup = mod.renderToStaticMarkup;
149
- }
150
- return _renderToStaticMarkup;
137
+ // src/slim-react/types.ts
138
+ var SLIM_ELEMENT = Symbol.for("react.element");
139
+ var FRAGMENT_TYPE = Symbol.for("react.fragment");
140
+ var SUSPENSE_TYPE = Symbol.for("react.suspense");
141
+
142
+ // src/slim-react/jsx.ts
143
+ var Fragment = FRAGMENT_TYPE;
144
+ function createElement(type, props, ...children) {
145
+ const normalizedProps = { ...props || {} };
146
+ if (children.length === 1) {
147
+ normalizedProps.children = children[0];
148
+ } else if (children.length > 1) {
149
+ normalizedProps.children = children;
150
+ }
151
+ const key = normalizedProps.key ?? null;
152
+ delete normalizedProps.key;
153
+ return {
154
+ $$typeof: SLIM_ELEMENT,
155
+ type,
156
+ props: normalizedProps,
157
+ key
158
+ };
159
+ }
160
+
161
+ // src/slim-react/renderContext.ts
162
+ var GLOBAL_KEY = "__slimReactRenderState";
163
+ var EMPTY = { id: 0, overflow: "", bits: 0 };
164
+ function s() {
165
+ const g = globalThis;
166
+ if (!g[GLOBAL_KEY]) {
167
+ g[GLOBAL_KEY] = { currentTreeContext: { ...EMPTY }, localIdCounter: 0, idPrefix: "" };
168
+ }
169
+ return g[GLOBAL_KEY];
170
+ }
171
+ function resetRenderState() {
172
+ const st = s();
173
+ st.currentTreeContext = { ...EMPTY };
174
+ st.localIdCounter = 0;
175
+ }
176
+ function pushTreeContext(totalChildren, index) {
177
+ const st = s();
178
+ const saved = { ...st.currentTreeContext };
179
+ const pendingBits = 32 - Math.clz32(totalChildren);
180
+ const slot = index + 1;
181
+ const totalBits = st.currentTreeContext.bits + pendingBits;
182
+ if (totalBits <= 30) {
183
+ st.currentTreeContext = {
184
+ id: st.currentTreeContext.id << pendingBits | slot,
185
+ overflow: st.currentTreeContext.overflow,
186
+ bits: totalBits
187
+ };
188
+ } else {
189
+ let newOverflow = st.currentTreeContext.overflow;
190
+ if (st.currentTreeContext.bits > 0)
191
+ newOverflow += st.currentTreeContext.id.toString(32);
192
+ st.currentTreeContext = { id: 1 << pendingBits | slot, overflow: newOverflow, bits: pendingBits };
193
+ }
194
+ return saved;
195
+ }
196
+ function popTreeContext(saved) {
197
+ s().currentTreeContext = saved;
198
+ }
199
+ function pushComponentScope() {
200
+ const st = s();
201
+ const saved = st.localIdCounter;
202
+ st.localIdCounter = 0;
203
+ return saved;
204
+ }
205
+ function popComponentScope(saved) {
206
+ s().localIdCounter = saved;
207
+ }
208
+ function snapshotContext() {
209
+ const st = s();
210
+ return { tree: { ...st.currentTreeContext }, localId: st.localIdCounter };
211
+ }
212
+ function restoreContext(snap) {
213
+ const st = s();
214
+ st.currentTreeContext = { ...snap.tree };
215
+ st.localIdCounter = snap.localId;
216
+ }
217
+
218
+ // src/slim-react/render.ts
219
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
220
+ "area",
221
+ "base",
222
+ "br",
223
+ "col",
224
+ "embed",
225
+ "hr",
226
+ "img",
227
+ "input",
228
+ "link",
229
+ "meta",
230
+ "param",
231
+ "source",
232
+ "track",
233
+ "wbr"
234
+ ]);
235
+ function escapeHtml(str) {
236
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
237
+ }
238
+ function escapeAttr(str) {
239
+ return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
240
+ }
241
+ function styleObjectToString(style) {
242
+ return Object.entries(style).map(([key, value]) => {
243
+ const cssKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
244
+ return `${cssKey}:${value}`;
245
+ }).join(";");
246
+ }
247
+ var SVG_ATTR_MAP = {
248
+ // Presentation / geometry
249
+ accentHeight: "accent-height",
250
+ alignmentBaseline: "alignment-baseline",
251
+ arabicForm: "arabic-form",
252
+ baselineShift: "baseline-shift",
253
+ capHeight: "cap-height",
254
+ clipPath: "clip-path",
255
+ clipRule: "clip-rule",
256
+ colorInterpolation: "color-interpolation",
257
+ colorInterpolationFilters: "color-interpolation-filters",
258
+ colorProfile: "color-profile",
259
+ dominantBaseline: "dominant-baseline",
260
+ enableBackground: "enable-background",
261
+ fillOpacity: "fill-opacity",
262
+ fillRule: "fill-rule",
263
+ floodColor: "flood-color",
264
+ floodOpacity: "flood-opacity",
265
+ fontFamily: "font-family",
266
+ fontSize: "font-size",
267
+ fontSizeAdjust: "font-size-adjust",
268
+ fontStretch: "font-stretch",
269
+ fontStyle: "font-style",
270
+ fontVariant: "font-variant",
271
+ fontWeight: "font-weight",
272
+ glyphName: "glyph-name",
273
+ glyphOrientationHorizontal: "glyph-orientation-horizontal",
274
+ glyphOrientationVertical: "glyph-orientation-vertical",
275
+ horizAdvX: "horiz-adv-x",
276
+ horizOriginX: "horiz-origin-x",
277
+ imageRendering: "image-rendering",
278
+ letterSpacing: "letter-spacing",
279
+ lightingColor: "lighting-color",
280
+ markerEnd: "marker-end",
281
+ markerMid: "marker-mid",
282
+ markerStart: "marker-start",
283
+ overlinePosition: "overline-position",
284
+ overlineThickness: "overline-thickness",
285
+ paintOrder: "paint-order",
286
+ panose1: "panose-1",
287
+ pointerEvents: "pointer-events",
288
+ renderingIntent: "rendering-intent",
289
+ shapeRendering: "shape-rendering",
290
+ stopColor: "stop-color",
291
+ stopOpacity: "stop-opacity",
292
+ strikethroughPosition: "strikethrough-position",
293
+ strikethroughThickness: "strikethrough-thickness",
294
+ strokeDasharray: "stroke-dasharray",
295
+ strokeDashoffset: "stroke-dashoffset",
296
+ strokeLinecap: "stroke-linecap",
297
+ strokeLinejoin: "stroke-linejoin",
298
+ strokeMiterlimit: "stroke-miterlimit",
299
+ strokeOpacity: "stroke-opacity",
300
+ strokeWidth: "stroke-width",
301
+ textAnchor: "text-anchor",
302
+ textDecoration: "text-decoration",
303
+ textRendering: "text-rendering",
304
+ underlinePosition: "underline-position",
305
+ underlineThickness: "underline-thickness",
306
+ unicodeBidi: "unicode-bidi",
307
+ unicodeRange: "unicode-range",
308
+ unitsPerEm: "units-per-em",
309
+ vAlphabetic: "v-alphabetic",
310
+ vHanging: "v-hanging",
311
+ vIdeographic: "v-ideographic",
312
+ vMathematical: "v-mathematical",
313
+ vertAdvY: "vert-adv-y",
314
+ vertOriginX: "vert-origin-x",
315
+ vertOriginY: "vert-origin-y",
316
+ wordSpacing: "word-spacing",
317
+ writingMode: "writing-mode",
318
+ xHeight: "x-height",
319
+ // Namespace-prefixed
320
+ xlinkActuate: "xlink:actuate",
321
+ xlinkArcrole: "xlink:arcrole",
322
+ xlinkHref: "xlink:href",
323
+ xlinkRole: "xlink:role",
324
+ xlinkShow: "xlink:show",
325
+ xlinkTitle: "xlink:title",
326
+ xlinkType: "xlink:type",
327
+ xmlBase: "xml:base",
328
+ xmlLang: "xml:lang",
329
+ xmlSpace: "xml:space",
330
+ xmlns: "xmlns",
331
+ xmlnsXlink: "xmlns:xlink",
332
+ // Filter / lighting
333
+ baseFrequency: "baseFrequency",
334
+ colorInterpolation_filters: "color-interpolation-filters",
335
+ diffuseConstant: "diffuseConstant",
336
+ edgeMode: "edgeMode",
337
+ filterUnits: "filterUnits",
338
+ gradientTransform: "gradientTransform",
339
+ gradientUnits: "gradientUnits",
340
+ kernelMatrix: "kernelMatrix",
341
+ kernelUnitLength: "kernelUnitLength",
342
+ lengthAdjust: "lengthAdjust",
343
+ limitingConeAngle: "limitingConeAngle",
344
+ markerHeight: "markerHeight",
345
+ markerWidth: "markerWidth",
346
+ maskContentUnits: "maskContentUnits",
347
+ maskUnits: "maskUnits",
348
+ numOctaves: "numOctaves",
349
+ pathLength: "pathLength",
350
+ patternContentUnits: "patternContentUnits",
351
+ patternTransform: "patternTransform",
352
+ patternUnits: "patternUnits",
353
+ pointsAtX: "pointsAtX",
354
+ pointsAtY: "pointsAtY",
355
+ pointsAtZ: "pointsAtZ",
356
+ preserveAspectRatio: "preserveAspectRatio",
357
+ primitiveUnits: "primitiveUnits",
358
+ refX: "refX",
359
+ refY: "refY",
360
+ repeatCount: "repeatCount",
361
+ repeatDur: "repeatDur",
362
+ specularConstant: "specularConstant",
363
+ specularExponent: "specularExponent",
364
+ spreadMethod: "spreadMethod",
365
+ startOffset: "startOffset",
366
+ stdDeviation: "stdDeviation",
367
+ stitchTiles: "stitchTiles",
368
+ surfaceScale: "surfaceScale",
369
+ systemLanguage: "systemLanguage",
370
+ tableValues: "tableValues",
371
+ targetX: "targetX",
372
+ targetY: "targetY",
373
+ textLength: "textLength",
374
+ viewBox: "viewBox",
375
+ xChannelSelector: "xChannelSelector",
376
+ yChannelSelector: "yChannelSelector"
377
+ };
378
+ function renderAttributes(props, isSvg) {
379
+ let attrs = "";
380
+ for (const [key, value] of Object.entries(props)) {
381
+ if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML")
382
+ continue;
383
+ if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
384
+ continue;
385
+ let attrName;
386
+ if (isSvg && key in SVG_ATTR_MAP) {
387
+ attrName = SVG_ATTR_MAP[key];
388
+ } else {
389
+ attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key;
390
+ }
391
+ if (value === false || value == null)
392
+ continue;
393
+ if (value === true) {
394
+ attrs += ` ${attrName}`;
395
+ continue;
396
+ }
397
+ if (key === "style" && typeof value === "object") {
398
+ attrs += ` style="${escapeAttr(styleObjectToString(value))}"`;
399
+ continue;
400
+ }
401
+ attrs += ` ${attrName}="${escapeAttr(String(value))}"`;
402
+ }
403
+ return attrs;
404
+ }
405
+ var BufferWriter = class {
406
+ chunks = [];
407
+ write(chunk) {
408
+ this.chunks.push(chunk);
409
+ }
410
+ flush(target) {
411
+ for (const c of this.chunks)
412
+ target.write(c);
413
+ }
414
+ };
415
+ function renderNode(node, writer, isSvg = false) {
416
+ if (node == null || typeof node === "boolean")
417
+ return;
418
+ if (typeof node === "string") {
419
+ writer.write(escapeHtml(node));
420
+ return;
421
+ }
422
+ if (typeof node === "number") {
423
+ writer.write(String(node));
424
+ return;
425
+ }
426
+ if (Array.isArray(node)) {
427
+ return renderChildArray(node, writer, isSvg);
428
+ }
429
+ if (typeof node === "object" && node !== null && Symbol.iterator in node && !("$$typeof" in node)) {
430
+ return renderChildArray(
431
+ Array.from(node),
432
+ writer,
433
+ isSvg
434
+ );
435
+ }
436
+ if (typeof node === "object" && node !== null && "$$typeof" in node && node.$$typeof === SLIM_ELEMENT) {
437
+ const element = node;
438
+ const { type, props } = element;
439
+ if (type === FRAGMENT_TYPE) {
440
+ return renderChildren(props.children, writer, isSvg);
441
+ }
442
+ if (type === SUSPENSE_TYPE) {
443
+ return renderSuspense(props, writer, isSvg);
444
+ }
445
+ if (typeof type === "function") {
446
+ return renderComponent(type, props, writer, isSvg);
447
+ }
448
+ if (typeof type === "string") {
449
+ return renderHostElement(type, props, writer, isSvg);
450
+ }
451
+ }
452
+ }
453
+ function renderHostElement(tag, props, writer, isSvg) {
454
+ const enteringSvg = tag === "svg";
455
+ const childSvg = isSvg || enteringSvg;
456
+ const effectiveProps = enteringSvg && !props.xmlns ? { xmlns: "http://www.w3.org/2000/svg", ...props } : props;
457
+ writer.write(`<${tag}${renderAttributes(effectiveProps, childSvg)}>`);
458
+ const childContext = tag === "foreignObject" ? false : childSvg;
459
+ let inner = void 0;
460
+ if (props.dangerouslySetInnerHTML) {
461
+ writer.write(props.dangerouslySetInnerHTML.__html);
462
+ } else {
463
+ inner = renderChildren(props.children, writer, childContext);
464
+ }
465
+ if (inner && typeof inner.then === "function") {
466
+ return inner.then(() => {
467
+ if (!VOID_ELEMENTS.has(tag))
468
+ writer.write(`</${tag}>`);
469
+ });
470
+ }
471
+ if (!VOID_ELEMENTS.has(tag))
472
+ writer.write(`</${tag}>`);
473
+ }
474
+ var REACT_MEMO = Symbol.for("react.memo");
475
+ var REACT_FORWARD_REF = Symbol.for("react.forward_ref");
476
+ var REACT_PROVIDER = Symbol.for("react.provider");
477
+ var REACT_CONTEXT = Symbol.for("react.context");
478
+ function renderComponent(type, props, writer, isSvg) {
479
+ const typeOf = type?.$$typeof;
480
+ if (typeOf === REACT_MEMO) {
481
+ return renderNode(
482
+ { $$typeof: SLIM_ELEMENT, type: type.type, props, key: null },
483
+ writer,
484
+ isSvg
485
+ );
486
+ }
487
+ if (typeOf === REACT_FORWARD_REF) {
488
+ return renderComponent(type.render, props, writer, isSvg);
489
+ }
490
+ const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
491
+ let prevCtxValue;
492
+ let ctx;
493
+ if (isProvider) {
494
+ ctx = type._context ?? type;
495
+ prevCtxValue = ctx._currentValue;
496
+ ctx._currentValue = props.value;
497
+ }
498
+ const savedScope = pushComponentScope();
499
+ let result;
500
+ try {
501
+ if (type.prototype && typeof type.prototype.render === "function") {
502
+ const instance = new type(props);
503
+ result = instance.render();
504
+ } else {
505
+ result = type(props);
506
+ }
507
+ } catch (e) {
508
+ popComponentScope(savedScope);
509
+ if (isProvider)
510
+ ctx._currentValue = prevCtxValue;
511
+ throw e;
512
+ }
513
+ const finish = () => {
514
+ popComponentScope(savedScope);
515
+ if (isProvider)
516
+ ctx._currentValue = prevCtxValue;
517
+ };
518
+ if (result instanceof Promise) {
519
+ return result.then((resolved) => {
520
+ const r2 = renderNode(resolved, writer, isSvg);
521
+ if (r2 && typeof r2.then === "function") {
522
+ return r2.then(finish);
523
+ }
524
+ finish();
525
+ });
526
+ }
527
+ const r = renderNode(result, writer, isSvg);
528
+ if (r && typeof r.then === "function") {
529
+ return r.then(finish);
530
+ }
531
+ finish();
151
532
  }
533
+ function isTextLike(node) {
534
+ return typeof node === "string" || typeof node === "number";
535
+ }
536
+ function renderChildArray(children, writer, isSvg) {
537
+ const totalChildren = children.length;
538
+ for (let i = 0; i < totalChildren; i++) {
539
+ if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
540
+ writer.write("<!-- -->");
541
+ }
542
+ const savedTree = pushTreeContext(totalChildren, i);
543
+ const r = renderNode(children[i], writer, isSvg);
544
+ if (r && typeof r.then === "function") {
545
+ return r.then(() => {
546
+ popTreeContext(savedTree);
547
+ return renderChildArrayFrom(children, i + 1, writer, isSvg);
548
+ });
549
+ }
550
+ popTreeContext(savedTree);
551
+ }
552
+ }
553
+ function renderChildArrayFrom(children, startIndex, writer, isSvg) {
554
+ const totalChildren = children.length;
555
+ for (let i = startIndex; i < totalChildren; i++) {
556
+ if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
557
+ writer.write("<!-- -->");
558
+ }
559
+ const savedTree = pushTreeContext(totalChildren, i);
560
+ const r = renderNode(children[i], writer, isSvg);
561
+ if (r && typeof r.then === "function") {
562
+ return r.then(() => {
563
+ popTreeContext(savedTree);
564
+ return renderChildArrayFrom(children, i + 1, writer, isSvg);
565
+ });
566
+ }
567
+ popTreeContext(savedTree);
568
+ }
569
+ }
570
+ function renderChildren(children, writer, isSvg = false) {
571
+ if (children == null)
572
+ return;
573
+ if (Array.isArray(children)) {
574
+ return renderChildArray(children, writer, isSvg);
575
+ }
576
+ return renderNode(children, writer, isSvg);
577
+ }
578
+ var MAX_SUSPENSE_RETRIES = 25;
579
+ async function renderSuspense(props, writer, isSvg = false) {
580
+ const { children, fallback } = props;
581
+ let attempts = 0;
582
+ const snap = snapshotContext();
583
+ while (attempts < MAX_SUSPENSE_RETRIES) {
584
+ restoreContext(snap);
585
+ try {
586
+ const buffer = new BufferWriter();
587
+ const r = renderNode(children, buffer, isSvg);
588
+ if (r && typeof r.then === "function") {
589
+ await r;
590
+ }
591
+ writer.write("<!--$-->");
592
+ buffer.flush(writer);
593
+ writer.write("<!--/$-->");
594
+ return;
595
+ } catch (error) {
596
+ if (error && typeof error.then === "function") {
597
+ await error;
598
+ attempts++;
599
+ } else {
600
+ throw error;
601
+ }
602
+ }
603
+ }
604
+ restoreContext(snap);
605
+ writer.write("<!--$?-->");
606
+ if (fallback) {
607
+ const r = renderNode(fallback, writer, isSvg);
608
+ if (r && typeof r.then === "function")
609
+ await r;
610
+ }
611
+ writer.write("<!--/$-->");
612
+ }
613
+ async function renderToString(element) {
614
+ for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
615
+ resetRenderState();
616
+ const chunks = [];
617
+ const writer = { write(c) {
618
+ chunks.push(c);
619
+ } };
620
+ try {
621
+ const r = renderNode(element, writer);
622
+ if (r && typeof r.then === "function")
623
+ await r;
624
+ return chunks.join("");
625
+ } catch (error) {
626
+ if (error && typeof error.then === "function") {
627
+ await error;
628
+ continue;
629
+ }
630
+ throw error;
631
+ }
632
+ }
633
+ throw new Error("[slim-react] renderToString exceeded maximum retries");
634
+ }
635
+
636
+ // src/utils/response.tsx
152
637
  var ESC = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" };
153
- var escAttr = (s) => s.replace(/[&<>"]/g, (c) => ESC[c] ?? c);
154
- var escText = (s) => s.replace(/[&<>]/g, (c) => ESC[c] ?? c);
638
+ var escAttr = (s2) => s2.replace(/[&<>"]/g, (c) => ESC[c] ?? c);
639
+ var escText = (s2) => s2.replace(/[&<>]/g, (c) => ESC[c] ?? c);
155
640
  var ATTR = {
156
641
  className: "class",
157
642
  htmlFor: "for",
@@ -195,77 +680,57 @@ var getHeadHtml = (seoData) => {
195
680
  var getReactResponse = async (req, opts) => {
196
681
  const App = opts.document.body;
197
682
  const { getInitProps, getAfterRenderProps, getFinalProps } = opts.document;
198
- const renderToStaticMarkup = await getStaticMarkupRenderer();
199
- const unsuspend = {
200
- cache: /* @__PURE__ */ new Map(),
201
- hasPending: false
202
- };
203
- const processUnsuspend = async () => {
204
- const pending = [...unsuspend.cache.values()].filter((e) => e.status === "pending").map((e) => e.promise);
205
- await Promise.all(pending);
206
- };
207
683
  const context = {
208
- head: {
209
- title: "Hadars App",
210
- meta: {},
211
- link: {},
212
- style: {},
213
- script: {},
214
- status: 200
215
- },
216
- _unsuspend: unsuspend
684
+ head: { title: "Hadars App", meta: {}, link: {}, style: {}, script: {}, status: 200 }
217
685
  };
218
686
  let props = {
219
687
  ...getInitProps ? await getInitProps(req) : {},
220
688
  location: req.location,
221
689
  context
222
690
  };
223
- let html = "";
224
- let iters = 0;
225
- do {
226
- unsuspend.hasPending = false;
227
- try {
228
- globalThis.__hadarsUnsuspend = unsuspend;
229
- html = renderToStaticMarkup(/* @__PURE__ */ jsx(App, { ...props }));
230
- } finally {
231
- globalThis.__hadarsUnsuspend = null;
232
- }
233
- if (unsuspend.hasPending)
234
- await processUnsuspend();
235
- } while (unsuspend.hasPending && ++iters < 25);
236
- if (unsuspend.hasPending) {
237
- console.warn("[hadars] SSR render loop hit the 25-iteration cap \u2014 some useServerData values may not be resolved. Check for data dependencies that are never fulfilled.");
238
- }
239
- if (getAfterRenderProps) {
240
- props = await getAfterRenderProps(props, html);
241
- try {
242
- globalThis.__hadarsUnsuspend = unsuspend;
243
- renderToStaticMarkup(/* @__PURE__ */ jsx(App, { ...{ ...props, location: req.location, context } }));
244
- } finally {
245
- globalThis.__hadarsUnsuspend = null;
691
+ const unsuspend = { cache: /* @__PURE__ */ new Map() };
692
+ globalThis.__hadarsUnsuspend = unsuspend;
693
+ try {
694
+ let html = await renderToString(createElement(App, props));
695
+ if (getAfterRenderProps) {
696
+ props = await getAfterRenderProps(props, html);
697
+ await renderToString(
698
+ createElement(App, { ...props, location: req.location, context })
699
+ );
246
700
  }
701
+ } finally {
702
+ globalThis.__hadarsUnsuspend = null;
247
703
  }
704
+ const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
248
705
  const serverData = {};
249
- for (const [k, v] of unsuspend.cache) {
250
- if (v.status === "fulfilled")
251
- serverData[k] = v.value;
706
+ for (const [key, entry] of unsuspend.cache) {
707
+ if (entry.status === "fulfilled")
708
+ serverData[key] = entry.value;
252
709
  }
253
- const { context: _, ...restProps } = getFinalProps ? await getFinalProps(props) : props;
254
710
  const clientProps = {
255
711
  ...restProps,
256
712
  location: req.location,
257
713
  ...Object.keys(serverData).length > 0 ? { __serverData: serverData } : {}
258
714
  };
259
- const ReactPage = /* @__PURE__ */ jsxs(Fragment, { children: [
260
- /* @__PURE__ */ jsx("div", { id: "app", children: /* @__PURE__ */ jsx(App, { ...{
261
- ...props,
262
- location: req.location,
263
- context
264
- } }) }),
265
- /* @__PURE__ */ jsx("script", { id: "hadars", type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c") } })
266
- ] });
715
+ const ReactPage = createElement(
716
+ Fragment,
717
+ null,
718
+ createElement(
719
+ "div",
720
+ { id: "app" },
721
+ createElement(App, { ...props, location: req.location, context })
722
+ ),
723
+ createElement("script", {
724
+ id: "hadars",
725
+ type: "application/json",
726
+ dangerouslySetInnerHTML: {
727
+ __html: JSON.stringify({ hadars: { props: clientProps } }).replace(/</g, "\\u003c")
728
+ }
729
+ })
730
+ );
267
731
  return {
268
732
  ReactPage,
733
+ unsuspend,
269
734
  status: context.head.status,
270
735
  headHtml: getHeadHtml(context.head),
271
736
  renderPayload: {
@@ -280,12 +745,12 @@ import rspack from "@rspack/core";
280
745
  import ReactRefreshPlugin from "@rspack/plugin-react-refresh";
281
746
  import path from "node:path";
282
747
  import { fileURLToPath } from "node:url";
283
- import pathMod2 from "node:path";
748
+ import pathMod from "node:path";
284
749
  import { existsSync } from "node:fs";
285
750
  var __dirname = process.cwd();
286
- var packageDir = pathMod2.dirname(fileURLToPath(import.meta.url));
287
- var clientScriptPath = pathMod2.resolve(packageDir, "template.html");
288
- var loaderPath = existsSync(pathMod2.resolve(packageDir, "loader.cjs")) ? pathMod2.resolve(packageDir, "loader.cjs") : pathMod2.resolve(packageDir, "loader.ts");
751
+ var packageDir = pathMod.dirname(fileURLToPath(import.meta.url));
752
+ var clientScriptPath = pathMod.resolve(packageDir, "template.html");
753
+ var loaderPath = existsSync(pathMod.resolve(packageDir, "loader.cjs")) ? pathMod.resolve(packageDir, "loader.cjs") : pathMod.resolve(packageDir, "loader.ts");
289
754
  var getConfigBase = (mode) => {
290
755
  const isDev = mode === "development";
291
756
  return {
@@ -445,25 +910,21 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
445
910
  const isServerBuild = Boolean(
446
911
  opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
447
912
  );
913
+ const slimReactIndex = pathMod.resolve(packageDir, "slim-react", "index.js");
914
+ const slimReactJsx = pathMod.resolve(packageDir, "slim-react", "jsx-runtime.js");
448
915
  const resolveAliases = isServerBuild ? {
449
- // force all react imports to resolve to this project's react
450
- react: path.resolve(process.cwd(), "node_modules", "react"),
451
- "react-dom": path.resolve(process.cwd(), "node_modules", "react-dom"),
452
- // also map react/jsx-runtime to avoid duplicates when automatic runtime is used
453
- "react/jsx-runtime": path.resolve(process.cwd(), "node_modules", "react", "jsx-runtime.js"),
454
- "react/jsx-dev-runtime": path.resolve(process.cwd(), "node_modules", "react", "jsx-dev-runtime.js"),
455
- // ensure emotion packages resolve to the project's node_modules so we don't pick up a browser-specific entry
916
+ // Route all React imports to slim-react for SSR.
917
+ react: slimReactIndex,
918
+ "react/jsx-runtime": slimReactJsx,
919
+ "react/jsx-dev-runtime": slimReactJsx,
920
+ // Keep emotion on the project's node_modules (server-safe entry).
456
921
  "@emotion/react": path.resolve(process.cwd(), "node_modules", "@emotion", "react"),
457
922
  "@emotion/server": path.resolve(process.cwd(), "node_modules", "@emotion", "server"),
458
923
  "@emotion/cache": path.resolve(process.cwd(), "node_modules", "@emotion", "cache"),
459
924
  "@emotion/styled": path.resolve(process.cwd(), "node_modules", "@emotion", "styled")
460
925
  } : void 0;
461
926
  const externals = isServerBuild ? [
462
- "react",
463
- "react-dom",
464
- // keep common aliases external as well
465
- "react/jsx-runtime",
466
- "react/jsx-dev-runtime",
927
+ // react / react-dom are replaced by slim-react via alias above — not external.
467
928
  // emotion should be external on server builds to avoid client/browser code
468
929
  "@emotion/react",
469
930
  "@emotion/server",
@@ -507,16 +968,44 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
507
968
  clean: false
508
969
  },
509
970
  mode: opts.mode,
971
+ // Persist transformed modules to disk — subsequent starts only recompile
972
+ // changed files, making repeat dev starts significantly faster.
973
+ cache: true,
510
974
  externals,
511
975
  ...optimization !== void 0 ? { optimization } : {},
512
976
  plugins: [
513
977
  new rspack.HtmlRspackPlugin({
514
978
  publicPath: base || "/",
515
- template: opts.htmlTemplate ? pathMod2.resolve(process.cwd(), opts.htmlTemplate) : clientScriptPath,
979
+ template: opts.htmlTemplate ? pathMod.resolve(process.cwd(), opts.htmlTemplate) : clientScriptPath,
516
980
  scriptLoading: "module",
517
981
  filename: "out.html",
518
- inject: "body"
982
+ inject: "head",
983
+ minify: opts.mode === "production"
519
984
  }),
985
+ // Add `async` to the emitted module script so DOMContentLoaded fires
986
+ // as soon as HTML is parsed — without waiting for the bundle to execute.
987
+ // `<script type="module" async>` is valid: it downloads in parallel and
988
+ // executes without blocking DOMContentLoaded, while retaining module
989
+ // semantics (strict mode, ES imports, etc.).
990
+ {
991
+ apply(compiler) {
992
+ compiler.hooks.emit.tapAsync("HadarsAsyncModuleScript", (compilation, cb) => {
993
+ const asset = compilation.assets["out.html"];
994
+ if (asset) {
995
+ const html = asset.source();
996
+ const updated = html.replace(
997
+ /(<script\b[^>]*\btype="module"[^>]*)(>)/g,
998
+ (match, before, end) => before.includes("async") ? match : `${before} async${end}`
999
+ );
1000
+ compilation.assets["out.html"] = {
1001
+ source: () => updated,
1002
+ size: () => Buffer.byteLength(updated)
1003
+ };
1004
+ }
1005
+ cb();
1006
+ });
1007
+ }
1008
+ },
520
1009
  isDev && new ReactRefreshPlugin(),
521
1010
  includeHotPlugin && isDev && new rspack.HotModuleReplacementPlugin(),
522
1011
  ...extraPlugins
@@ -774,15 +1263,55 @@ async function tryServeFile(filePath) {
774
1263
 
775
1264
  // src/build.ts
776
1265
  import { RspackDevServer } from "@rspack/dev-server";
777
- import pathMod3 from "node:path";
778
- import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
779
- import { createRequire as createRequire2 } from "node:module";
1266
+ import pathMod2 from "node:path";
1267
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
780
1268
  import crypto from "node:crypto";
781
1269
  import fs from "node:fs/promises";
782
1270
  import { existsSync as existsSync2 } from "node:fs";
783
1271
  import os from "node:os";
784
1272
  import { spawn } from "node:child_process";
785
1273
  import cluster from "node:cluster";
1274
+
1275
+ // src/utils/segmentCache.ts
1276
+ function getStore() {
1277
+ const g = globalThis;
1278
+ if (!g.__hadarsSegmentStore) {
1279
+ g.__hadarsSegmentStore = /* @__PURE__ */ new Map();
1280
+ }
1281
+ return g.__hadarsSegmentStore;
1282
+ }
1283
+ function setSegment(key, html, ttl) {
1284
+ getStore().set(key, {
1285
+ html,
1286
+ expiresAt: ttl != null ? Date.now() + ttl : null
1287
+ });
1288
+ }
1289
+ function processSegmentCache(html) {
1290
+ let prev;
1291
+ do {
1292
+ prev = html;
1293
+ html = html.replace(
1294
+ /<hadars-c([^>]*)>([\s\S]*?)<\/hadars-c>/g,
1295
+ (match, attrs, content) => {
1296
+ const cacheM = /data-cache="([^"]+)"/.exec(attrs);
1297
+ const keyM = /data-key="([^"]+)"/.exec(attrs);
1298
+ const ttlM = /data-ttl="(\d+)"/.exec(attrs);
1299
+ if (!cacheM || !keyM)
1300
+ return match;
1301
+ if (cacheM[1] === "miss") {
1302
+ setSegment(keyM[1], content, ttlM ? Number(ttlM[1]) : void 0);
1303
+ return content;
1304
+ }
1305
+ if (cacheM[1] === "hit")
1306
+ return content;
1307
+ return match;
1308
+ }
1309
+ );
1310
+ } while (html !== prev);
1311
+ return html;
1312
+ }
1313
+
1314
+ // src/build.ts
786
1315
  var encoder = new TextEncoder();
787
1316
  async function processHtmlTemplate(templatePath) {
788
1317
  const html = await fs.readFile(templatePath, "utf-8");
@@ -794,6 +1323,14 @@ async function processHtmlTemplate(templatePath) {
794
1323
  }
795
1324
  if (matches.length === 0)
796
1325
  return templatePath;
1326
+ await ensureHadarsTmpDir();
1327
+ const sourceHash = crypto.createHash("md5").update(html).digest("hex").slice(0, 8);
1328
+ const cachedPath = pathMod2.join(HADARS_TMP_DIR, `template-${sourceHash}.html`);
1329
+ try {
1330
+ await fs.access(cachedPath);
1331
+ return cachedPath;
1332
+ } catch {
1333
+ }
797
1334
  const { default: postcss } = await import("postcss");
798
1335
  let plugins = [];
799
1336
  try {
@@ -811,22 +1348,11 @@ async function processHtmlTemplate(templatePath) {
811
1348
  console.warn("[hadars] PostCSS error processing <style> block in HTML template:", err);
812
1349
  }
813
1350
  }
814
- const tmpPath = pathMod3.join(os.tmpdir(), `hadars-template-${Date.now()}.html`);
815
- await fs.writeFile(tmpPath, processedHtml);
816
- return tmpPath;
1351
+ await fs.writeFile(cachedPath, processedHtml);
1352
+ return cachedPath;
817
1353
  }
818
1354
  var HEAD_MARKER = '<meta name="HADARS_HEAD">';
819
1355
  var BODY_MARKER = '<meta name="HADARS_BODY">';
820
- var _renderToString = null;
821
- async function getRenderToString() {
822
- if (!_renderToString) {
823
- const req = createRequire2(pathMod3.resolve(process.cwd(), "__hadars_fake__.js"));
824
- const resolved = req.resolve("react-dom/server");
825
- const mod = await import(pathToFileURL2(resolved).href);
826
- _renderToString = mod.renderToString;
827
- }
828
- return _renderToString;
829
- }
830
1356
  var RenderWorkerPool = class {
831
1357
  workers = [];
832
1358
  pending = /* @__PURE__ */ new Map();
@@ -931,19 +1457,18 @@ var RenderWorkerPool = class {
931
1457
  }
932
1458
  };
933
1459
  async function buildSsrResponse(ReactPage, headHtml, status, getPrecontentHtml, unsuspendForRender) {
934
- const renderToString = await getRenderToString();
935
1460
  const responseStream = new ReadableStream({
936
1461
  async start(controller) {
937
1462
  const [precontentHtml, postContent] = await getPrecontentHtml(headHtml);
938
1463
  controller.enqueue(encoder.encode(precontentHtml));
939
- await Promise.resolve();
940
1464
  let bodyHtml;
941
1465
  try {
942
1466
  globalThis.__hadarsUnsuspend = unsuspendForRender;
943
- bodyHtml = renderToString(ReactPage);
1467
+ bodyHtml = await renderToString(ReactPage);
944
1468
  } finally {
945
1469
  globalThis.__hadarsUnsuspend = null;
946
1470
  }
1471
+ bodyHtml = processSegmentCache(bodyHtml);
947
1472
  controller.enqueue(encoder.encode(bodyHtml + postContent));
948
1473
  controller.close();
949
1474
  }
@@ -1072,6 +1597,8 @@ var __dirname2 = process.cwd();
1072
1597
  var getSuffix = (mode) => mode === "development" ? `?v=${Date.now()}` : "";
1073
1598
  var HadarsFolder = "./.hadars";
1074
1599
  var StaticPath = `${HadarsFolder}/static`;
1600
+ var HADARS_TMP_DIR = pathMod2.join(os.tmpdir(), "hadars");
1601
+ var ensureHadarsTmpDir = () => fs.mkdir(HADARS_TMP_DIR, { recursive: true });
1075
1602
  var validateOptions = (options) => {
1076
1603
  if (!options.entry) {
1077
1604
  throw new Error("Entry file is required");
@@ -1081,8 +1608,8 @@ var validateOptions = (options) => {
1081
1608
  }
1082
1609
  };
1083
1610
  var resolveWorkerCmd = (packageDir2) => {
1084
- const tsPath = pathMod3.resolve(packageDir2, "ssr-watch.ts");
1085
- const jsPath = pathMod3.resolve(packageDir2, "ssr-watch.js");
1611
+ const tsPath = pathMod2.resolve(packageDir2, "ssr-watch.ts");
1612
+ const jsPath = pathMod2.resolve(packageDir2, "ssr-watch.js");
1086
1613
  if (isBun && existsSync2(tsPath)) {
1087
1614
  return ["bun", tsPath];
1088
1615
  }
@@ -1116,10 +1643,10 @@ var dev = async (options) => {
1116
1643
  const handleProxy = createProxyHandler(options);
1117
1644
  const handleWS = upgradeHandler(options);
1118
1645
  const handler = options.fetch;
1119
- const entry = pathMod3.resolve(__dirname2, options.entry);
1646
+ const entry = pathMod2.resolve(__dirname2, options.entry);
1120
1647
  const hmrPort = options.hmrPort ?? port + 1;
1121
- const packageDir2 = pathMod3.dirname(fileURLToPath2(import.meta.url));
1122
- const clientScriptPath2 = pathMod3.resolve(packageDir2, "utils", "clientScript.tsx");
1648
+ const packageDir2 = pathMod2.dirname(fileURLToPath2(import.meta.url));
1649
+ const clientScriptPath2 = pathMod2.resolve(packageDir2, "utils", "clientScript.tsx");
1123
1650
  let clientScript = "";
1124
1651
  try {
1125
1652
  clientScript = (await fs.readFile(clientScriptPath2, "utf-8")).replace("$_MOD_PATH$", entry + getSuffix(options.mode));
@@ -1127,15 +1654,16 @@ var dev = async (options) => {
1127
1654
  console.error("Failed to read client script from package dist, falling back to src", err);
1128
1655
  throw err;
1129
1656
  }
1130
- const tmpFilePath = pathMod3.join(os.tmpdir(), `hadars-client-${Date.now()}.tsx`);
1657
+ await ensureHadarsTmpDir();
1658
+ const tmpFilePath = pathMod2.join(HADARS_TMP_DIR, `client-${Date.now()}.tsx`);
1131
1659
  await fs.writeFile(tmpFilePath, clientScript);
1132
1660
  let ssrBuildId = crypto.randomBytes(4).toString("hex");
1133
- const resolvedHtmlTemplate = options.htmlTemplate ? await processHtmlTemplate(pathMod3.resolve(__dirname2, options.htmlTemplate)) : void 0;
1661
+ const resolvedHtmlTemplate = options.htmlTemplate ? await processHtmlTemplate(pathMod2.resolve(__dirname2, options.htmlTemplate)) : void 0;
1134
1662
  const clientCompiler = createClientCompiler(tmpFilePath, {
1135
1663
  target: "web",
1136
1664
  output: {
1137
1665
  filename: "index.js",
1138
- path: pathMod3.resolve(__dirname2, StaticPath)
1666
+ path: pathMod2.resolve(__dirname2, StaticPath)
1139
1667
  },
1140
1668
  base: baseURL,
1141
1669
  mode: "development",
@@ -1234,29 +1762,31 @@ var dev = async (options) => {
1234
1762
  stdoutReader = null;
1235
1763
  }
1236
1764
  })();
1237
- await Promise.all([clientBuildDone, ssrBuildDone]);
1238
- if (stdoutReader) {
1239
- const reader = stdoutReader;
1240
- (async () => {
1241
- try {
1242
- while (true) {
1243
- const { done, value } = await reader.read();
1244
- if (done)
1245
- break;
1246
- const chunk = decoder.decode(value, { stream: true });
1247
- try {
1248
- process.stdout.write(chunk);
1249
- } catch (e) {
1250
- }
1251
- if (chunk.includes(rebuildMarker)) {
1252
- ssrBuildId = crypto.randomBytes(4).toString("hex");
1253
- console.log("[hadars] SSR bundle updated, build id:", ssrBuildId);
1765
+ const readyPromise = Promise.all([clientBuildDone, ssrBuildDone]);
1766
+ readyPromise.then(() => {
1767
+ if (stdoutReader) {
1768
+ const reader = stdoutReader;
1769
+ (async () => {
1770
+ try {
1771
+ while (true) {
1772
+ const { done, value } = await reader.read();
1773
+ if (done)
1774
+ break;
1775
+ const chunk = decoder.decode(value, { stream: true });
1776
+ try {
1777
+ process.stdout.write(chunk);
1778
+ } catch (e) {
1779
+ }
1780
+ if (chunk.includes(rebuildMarker)) {
1781
+ ssrBuildId = crypto.randomBytes(4).toString("hex");
1782
+ console.log("[hadars] SSR bundle updated, build id:", ssrBuildId);
1783
+ }
1254
1784
  }
1785
+ } catch (e) {
1255
1786
  }
1256
- } catch (e) {
1257
- }
1258
- })();
1259
- }
1787
+ })();
1788
+ }
1789
+ });
1260
1790
  (async () => {
1261
1791
  try {
1262
1792
  const r = stderrWebStream.getReader();
@@ -1273,9 +1803,10 @@ var dev = async (options) => {
1273
1803
  }
1274
1804
  })();
1275
1805
  const getPrecontentHtml = makePrecontentHtmlGetter(
1276
- fs.readFile(pathMod3.join(__dirname2, StaticPath, "out.html"), "utf-8")
1806
+ readyPromise.then(() => fs.readFile(pathMod2.join(__dirname2, StaticPath, "out.html"), "utf-8"))
1277
1807
  );
1278
1808
  await serve(port, async (req, ctx) => {
1809
+ await readyPromise;
1279
1810
  const request = parseRequest(req);
1280
1811
  if (handler) {
1281
1812
  const res = await handler(request);
@@ -1289,15 +1820,15 @@ var dev = async (options) => {
1289
1820
  return proxied;
1290
1821
  const url = new URL(request.url);
1291
1822
  const path2 = url.pathname;
1292
- const staticRes = await tryServeFile(pathMod3.join(__dirname2, StaticPath, path2));
1823
+ const staticRes = await tryServeFile(pathMod2.join(__dirname2, StaticPath, path2));
1293
1824
  if (staticRes)
1294
1825
  return staticRes;
1295
- const projectStaticPath = pathMod3.resolve(process.cwd(), "static");
1296
- const projectRes = await tryServeFile(pathMod3.join(projectStaticPath, path2));
1826
+ const projectStaticPath = pathMod2.resolve(process.cwd(), "static");
1827
+ const projectRes = await tryServeFile(pathMod2.join(projectStaticPath, path2));
1297
1828
  if (projectRes)
1298
1829
  return projectRes;
1299
- const ssrComponentPath = pathMod3.join(__dirname2, HadarsFolder, SSR_FILENAME);
1300
- const importPath = pathToFileURL2(ssrComponentPath).href + `?t=${ssrBuildId}`;
1830
+ const ssrComponentPath = pathMod2.join(__dirname2, HadarsFolder, SSR_FILENAME);
1831
+ const importPath = pathToFileURL(ssrComponentPath).href + `?t=${ssrBuildId}`;
1301
1832
  try {
1302
1833
  const {
1303
1834
  default: Component,
@@ -1305,7 +1836,7 @@ var dev = async (options) => {
1305
1836
  getAfterRenderProps,
1306
1837
  getFinalProps
1307
1838
  } = await import(importPath);
1308
- const { ReactPage, status, headHtml, renderPayload } = await getReactResponse(request, {
1839
+ const { ReactPage, unsuspend, status, headHtml } = await getReactResponse(request, {
1309
1840
  document: {
1310
1841
  body: Component,
1311
1842
  lang: "en",
@@ -1314,7 +1845,6 @@ var dev = async (options) => {
1314
1845
  getFinalProps
1315
1846
  }
1316
1847
  });
1317
- const unsuspend = renderPayload.appProps.context?._unsuspend ?? null;
1318
1848
  return buildSsrResponse(ReactPage, headHtml, status, getPrecontentHtml, unsuspend);
1319
1849
  } catch (err) {
1320
1850
  console.error("[hadars] SSR render error:", err);
@@ -1328,19 +1858,20 @@ var dev = async (options) => {
1328
1858
  };
1329
1859
  var build = async (options) => {
1330
1860
  validateOptions(options);
1331
- const entry = pathMod3.resolve(__dirname2, options.entry);
1332
- const packageDir2 = pathMod3.dirname(fileURLToPath2(import.meta.url));
1333
- const clientScriptPath2 = pathMod3.resolve(packageDir2, "utils", "clientScript.js");
1861
+ const entry = pathMod2.resolve(__dirname2, options.entry);
1862
+ const packageDir2 = pathMod2.dirname(fileURLToPath2(import.meta.url));
1863
+ const clientScriptPath2 = pathMod2.resolve(packageDir2, "utils", "clientScript.js");
1334
1864
  let clientScript = "";
1335
1865
  try {
1336
1866
  clientScript = (await fs.readFile(clientScriptPath2, "utf-8")).replace("$_MOD_PATH$", entry + getSuffix(options.mode));
1337
1867
  } catch (err) {
1338
- const srcClientPath = pathMod3.resolve(packageDir2, "utils", "clientScript.tsx");
1868
+ const srcClientPath = pathMod2.resolve(packageDir2, "utils", "clientScript.tsx");
1339
1869
  clientScript = (await fs.readFile(srcClientPath, "utf-8")).replace("$_MOD_PATH$", entry + `?v=${Date.now()}`);
1340
1870
  }
1341
- const tmpFilePath = pathMod3.join(os.tmpdir(), `hadars-client-${Date.now()}.tsx`);
1871
+ await ensureHadarsTmpDir();
1872
+ const tmpFilePath = pathMod2.join(HADARS_TMP_DIR, `client-${Date.now()}.tsx`);
1342
1873
  await fs.writeFile(tmpFilePath, clientScript);
1343
- const resolvedHtmlTemplate = options.htmlTemplate ? await processHtmlTemplate(pathMod3.resolve(__dirname2, options.htmlTemplate)) : void 0;
1874
+ const resolvedHtmlTemplate = options.htmlTemplate ? await processHtmlTemplate(pathMod2.resolve(__dirname2, options.htmlTemplate)) : void 0;
1344
1875
  console.log("Building client and server bundles in parallel...");
1345
1876
  await Promise.all([
1346
1877
  compileEntry(tmpFilePath, {
@@ -1348,7 +1879,7 @@ var build = async (options) => {
1348
1879
  output: {
1349
1880
  // Content hash: filename is stable when code is unchanged → better browser/CDN cache.
1350
1881
  filename: "index.[contenthash:8].js",
1351
- path: pathMod3.resolve(__dirname2, StaticPath)
1882
+ path: pathMod2.resolve(__dirname2, StaticPath)
1352
1883
  },
1353
1884
  base: options.baseURL,
1354
1885
  mode: "production",
@@ -1357,11 +1888,11 @@ var build = async (options) => {
1357
1888
  optimization: options.optimization,
1358
1889
  htmlTemplate: resolvedHtmlTemplate
1359
1890
  }),
1360
- compileEntry(pathMod3.resolve(__dirname2, options.entry), {
1891
+ compileEntry(pathMod2.resolve(__dirname2, options.entry), {
1361
1892
  output: {
1362
1893
  iife: false,
1363
1894
  filename: SSR_FILENAME,
1364
- path: pathMod3.resolve(__dirname2, HadarsFolder),
1895
+ path: pathMod2.resolve(__dirname2, HadarsFolder),
1365
1896
  publicPath: "",
1366
1897
  library: { type: "module" }
1367
1898
  },
@@ -1397,16 +1928,16 @@ var run = async (options) => {
1397
1928
  console.log(`Starting Hadars (run) on port ${port}`);
1398
1929
  let renderPool;
1399
1930
  if (!isNode && workers > 1) {
1400
- const packageDir2 = pathMod3.dirname(fileURLToPath2(import.meta.url));
1401
- const workerJs = pathMod3.resolve(packageDir2, "ssr-render-worker.js");
1402
- const workerTs = pathMod3.resolve(packageDir2, "ssr-render-worker.ts");
1931
+ const packageDir2 = pathMod2.dirname(fileURLToPath2(import.meta.url));
1932
+ const workerJs = pathMod2.resolve(packageDir2, "ssr-render-worker.js");
1933
+ const workerTs = pathMod2.resolve(packageDir2, "ssr-render-worker.ts");
1403
1934
  const workerFile = existsSync2(workerJs) ? workerJs : workerTs;
1404
- const ssrBundlePath = pathMod3.resolve(__dirname2, HadarsFolder, SSR_FILENAME);
1935
+ const ssrBundlePath = pathMod2.resolve(__dirname2, HadarsFolder, SSR_FILENAME);
1405
1936
  renderPool = new RenderWorkerPool(workerFile, workers, ssrBundlePath);
1406
1937
  console.log(`[hadars] SSR render pool: ${workers} worker threads`);
1407
1938
  }
1408
1939
  const getPrecontentHtml = makePrecontentHtmlGetter(
1409
- fs.readFile(pathMod3.join(__dirname2, StaticPath, "out.html"), "utf-8")
1940
+ fs.readFile(pathMod2.join(__dirname2, StaticPath, "out.html"), "utf-8")
1410
1941
  );
1411
1942
  const runHandler = async (req, ctx) => {
1412
1943
  const request = parseRequest(req);
@@ -1422,23 +1953,23 @@ var run = async (options) => {
1422
1953
  return proxied;
1423
1954
  const url = new URL(request.url);
1424
1955
  const path2 = url.pathname;
1425
- const staticRes = await tryServeFile(pathMod3.join(__dirname2, StaticPath, path2));
1956
+ const staticRes = await tryServeFile(pathMod2.join(__dirname2, StaticPath, path2));
1426
1957
  if (staticRes)
1427
1958
  return staticRes;
1428
- const projectStaticPath = pathMod3.resolve(process.cwd(), "static");
1429
- const projectRes = await tryServeFile(pathMod3.join(projectStaticPath, path2));
1959
+ const projectStaticPath = pathMod2.resolve(process.cwd(), "static");
1960
+ const projectRes = await tryServeFile(pathMod2.join(projectStaticPath, path2));
1430
1961
  if (projectRes)
1431
1962
  return projectRes;
1432
1963
  const routeClean = path2.replace(/(^\/|\/$)/g, "");
1433
1964
  if (routeClean) {
1434
1965
  const routeRes = await tryServeFile(
1435
- pathMod3.join(__dirname2, StaticPath, routeClean, "index.html")
1966
+ pathMod2.join(__dirname2, StaticPath, routeClean, "index.html")
1436
1967
  );
1437
1968
  if (routeRes)
1438
1969
  return routeRes;
1439
1970
  }
1440
- const componentPath = pathToFileURL2(
1441
- pathMod3.resolve(__dirname2, HadarsFolder, SSR_FILENAME)
1971
+ const componentPath = pathToFileURL(
1972
+ pathMod2.resolve(__dirname2, HadarsFolder, SSR_FILENAME)
1442
1973
  ).href;
1443
1974
  try {
1444
1975
  const {
@@ -1456,7 +1987,7 @@ var run = async (options) => {
1456
1987
  status: wStatus
1457
1988
  });
1458
1989
  }
1459
- const { ReactPage, status, headHtml, renderPayload } = await getReactResponse(request, {
1990
+ const { ReactPage, unsuspend, status, headHtml } = await getReactResponse(request, {
1460
1991
  document: {
1461
1992
  body: Component,
1462
1993
  lang: "en",
@@ -1465,7 +1996,6 @@ var run = async (options) => {
1465
1996
  getFinalProps
1466
1997
  }
1467
1998
  });
1468
- const unsuspend = renderPayload.appProps.context?._unsuspend ?? null;
1469
1999
  return buildSsrResponse(ReactPage, headHtml, status, getPrecontentHtml, unsuspend);
1470
2000
  } catch (err) {
1471
2001
  console.error("[hadars] SSR render error:", err);