hadars 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{chunk-2KJRDPCN.js → chunk-2J2L2H3H.js} +9 -9
- package/dist/{chunk-LY5MTHFV.js → chunk-TV37IMRB.js} +50 -51
- package/dist/cli.js +70 -67
- package/dist/cloudflare.cjs +56 -57
- package/dist/cloudflare.js +2 -2
- package/dist/lambda.cjs +58 -65
- package/dist/lambda.js +4 -10
- package/dist/slim-react/index.cjs +50 -51
- package/dist/slim-react/index.js +1 -1
- package/dist/ssr-render-worker.js +46 -47
- package/dist/ssr-watch.js +9 -6
- package/package.json +2 -2
- package/src/build.ts +9 -5
- package/src/lambda.ts +7 -14
- package/src/slim-react/render.ts +39 -25
- package/src/slim-react/renderContext.ts +34 -11
- package/src/utils/rspack.ts +9 -6
- package/src/utils/ssrHandler.ts +13 -8
|
@@ -218,7 +218,16 @@ function componentCalledUseId() {
|
|
|
218
218
|
function snapshotContext() {
|
|
219
219
|
const st = s();
|
|
220
220
|
const ctx = st.currentTreeContext;
|
|
221
|
-
|
|
221
|
+
const depth = _treeDepth;
|
|
222
|
+
return {
|
|
223
|
+
tree: { id: ctx.id, overflow: ctx.overflow },
|
|
224
|
+
localId: st.localIdCounter,
|
|
225
|
+
treeDepth: depth,
|
|
226
|
+
// Snapshot the live stack so that popTreeContext reads correct saved values
|
|
227
|
+
// even if another concurrent render's resetRenderState stomped the arrays.
|
|
228
|
+
idStack: _treeIdStack.slice(0, depth),
|
|
229
|
+
ovStack: _treeOvStack.slice(0, depth)
|
|
230
|
+
};
|
|
222
231
|
}
|
|
223
232
|
function restoreContext(snap) {
|
|
224
233
|
const st = s();
|
|
@@ -227,6 +236,10 @@ function restoreContext(snap) {
|
|
|
227
236
|
ctx.overflow = snap.tree.overflow;
|
|
228
237
|
st.localIdCounter = snap.localId;
|
|
229
238
|
_treeDepth = snap.treeDepth;
|
|
239
|
+
for (let i = 0; i < snap.treeDepth; i++) {
|
|
240
|
+
_treeIdStack[i] = snap.idStack[i];
|
|
241
|
+
_treeOvStack[i] = snap.ovStack[i];
|
|
242
|
+
}
|
|
230
243
|
}
|
|
231
244
|
function getTreeId() {
|
|
232
245
|
const { id, overflow } = s().currentTreeContext;
|
|
@@ -372,6 +385,14 @@ function restoreDispatcher(prev) {
|
|
|
372
385
|
}
|
|
373
386
|
|
|
374
387
|
// src/slim-react/render.ts
|
|
388
|
+
function captureRenderCtx() {
|
|
389
|
+
return { m: captureMap(), u: captureUnsuspend(), t: snapshotContext() };
|
|
390
|
+
}
|
|
391
|
+
function restoreRenderCtx(ctx) {
|
|
392
|
+
swapContextMap(ctx.m);
|
|
393
|
+
restoreUnsuspend(ctx.u);
|
|
394
|
+
restoreContext(ctx.t);
|
|
395
|
+
}
|
|
375
396
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
376
397
|
"area",
|
|
377
398
|
"base",
|
|
@@ -815,11 +836,9 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
815
836
|
if (e && typeof e.then === "function") {
|
|
816
837
|
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
817
838
|
patchPromiseStatus(e);
|
|
818
|
-
const
|
|
819
|
-
const u = captureUnsuspend();
|
|
839
|
+
const rctx = captureRenderCtx();
|
|
820
840
|
return e.then(() => {
|
|
821
|
-
|
|
822
|
-
restoreUnsuspend(u);
|
|
841
|
+
restoreRenderCtx(rctx);
|
|
823
842
|
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
824
843
|
});
|
|
825
844
|
}
|
|
@@ -856,17 +875,14 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
856
875
|
};
|
|
857
876
|
const r2 = renderChildren(props.children, writer, isSvg);
|
|
858
877
|
if (r2 && typeof r2.then === "function") {
|
|
859
|
-
const
|
|
860
|
-
const u = captureUnsuspend();
|
|
878
|
+
const rctx = captureRenderCtx();
|
|
861
879
|
return r2.then(
|
|
862
880
|
() => {
|
|
863
|
-
|
|
864
|
-
restoreUnsuspend(u);
|
|
881
|
+
restoreRenderCtx(rctx);
|
|
865
882
|
finish();
|
|
866
883
|
},
|
|
867
884
|
(e) => {
|
|
868
|
-
|
|
869
|
-
restoreUnsuspend(u);
|
|
885
|
+
restoreRenderCtx(rctx);
|
|
870
886
|
finish();
|
|
871
887
|
throw e;
|
|
872
888
|
}
|
|
@@ -895,11 +911,9 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
895
911
|
if (e && typeof e.then === "function") {
|
|
896
912
|
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
897
913
|
patchPromiseStatus(e);
|
|
898
|
-
const
|
|
899
|
-
const u = captureUnsuspend();
|
|
914
|
+
const rctx = captureRenderCtx();
|
|
900
915
|
return e.then(() => {
|
|
901
|
-
|
|
902
|
-
restoreUnsuspend(u);
|
|
916
|
+
restoreRenderCtx(rctx);
|
|
903
917
|
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
904
918
|
});
|
|
905
919
|
}
|
|
@@ -911,30 +925,25 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
911
925
|
savedIdTree = pushTreeContext(1, 0);
|
|
912
926
|
}
|
|
913
927
|
if (result instanceof Promise) {
|
|
914
|
-
const
|
|
915
|
-
const u = captureUnsuspend();
|
|
928
|
+
const rctx = captureRenderCtx();
|
|
916
929
|
return result.then((resolved) => {
|
|
917
|
-
|
|
918
|
-
restoreUnsuspend(u);
|
|
930
|
+
restoreRenderCtx(rctx);
|
|
919
931
|
let asyncSavedIdTree;
|
|
920
932
|
if (componentCalledUseId()) {
|
|
921
933
|
asyncSavedIdTree = pushTreeContext(1, 0);
|
|
922
934
|
}
|
|
923
935
|
const r2 = renderNode(resolved, writer, isSvg);
|
|
924
936
|
if (r2 && typeof r2.then === "function") {
|
|
925
|
-
const
|
|
926
|
-
const u2 = captureUnsuspend();
|
|
937
|
+
const rctx2 = captureRenderCtx();
|
|
927
938
|
return r2.then(
|
|
928
939
|
() => {
|
|
929
|
-
|
|
930
|
-
restoreUnsuspend(u2);
|
|
940
|
+
restoreRenderCtx(rctx2);
|
|
931
941
|
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
932
942
|
popComponentScope(savedScope);
|
|
933
943
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
934
944
|
},
|
|
935
945
|
(e) => {
|
|
936
|
-
|
|
937
|
-
restoreUnsuspend(u2);
|
|
946
|
+
restoreRenderCtx(rctx2);
|
|
938
947
|
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
939
948
|
popComponentScope(savedScope);
|
|
940
949
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
@@ -946,8 +955,7 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
946
955
|
popComponentScope(savedScope);
|
|
947
956
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
948
957
|
}, (e) => {
|
|
949
|
-
|
|
950
|
-
restoreUnsuspend(u);
|
|
958
|
+
restoreRenderCtx(rctx);
|
|
951
959
|
popComponentScope(savedScope);
|
|
952
960
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
953
961
|
throw e;
|
|
@@ -955,19 +963,16 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
955
963
|
}
|
|
956
964
|
const r = renderNode(result, writer, isSvg);
|
|
957
965
|
if (r && typeof r.then === "function") {
|
|
958
|
-
const
|
|
959
|
-
const u = captureUnsuspend();
|
|
966
|
+
const rctx = captureRenderCtx();
|
|
960
967
|
return r.then(
|
|
961
968
|
() => {
|
|
962
|
-
|
|
963
|
-
restoreUnsuspend(u);
|
|
969
|
+
restoreRenderCtx(rctx);
|
|
964
970
|
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
965
971
|
popComponentScope(savedScope);
|
|
966
972
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
967
973
|
},
|
|
968
974
|
(e) => {
|
|
969
|
-
|
|
970
|
-
restoreUnsuspend(u);
|
|
975
|
+
restoreRenderCtx(rctx);
|
|
971
976
|
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
972
977
|
popComponentScope(savedScope);
|
|
973
978
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
@@ -992,11 +997,9 @@ function renderChildArrayFrom(children, startIndex, writer, isSvg) {
|
|
|
992
997
|
const savedTree = pushTreeContext(totalChildren, i);
|
|
993
998
|
const r = renderNode(child, writer, isSvg);
|
|
994
999
|
if (r && typeof r.then === "function") {
|
|
995
|
-
const
|
|
996
|
-
const u = captureUnsuspend();
|
|
1000
|
+
const rctx = captureRenderCtx();
|
|
997
1001
|
return r.then(() => {
|
|
998
|
-
|
|
999
|
-
restoreUnsuspend(u);
|
|
1002
|
+
restoreRenderCtx(rctx);
|
|
1000
1003
|
popTreeContext(savedTree);
|
|
1001
1004
|
return renderChildArrayFrom(children, i + 1, writer, isSvg);
|
|
1002
1005
|
});
|
|
@@ -1020,11 +1023,9 @@ async function renderSuspense(props, writer, isSvg = false) {
|
|
|
1020
1023
|
try {
|
|
1021
1024
|
const r = renderNode(children, buffer, isSvg);
|
|
1022
1025
|
if (r && typeof r.then === "function") {
|
|
1023
|
-
const
|
|
1024
|
-
const u = captureUnsuspend();
|
|
1026
|
+
const rctx = captureRenderCtx();
|
|
1025
1027
|
await r;
|
|
1026
|
-
|
|
1027
|
-
restoreUnsuspend(u);
|
|
1028
|
+
restoreRenderCtx(rctx);
|
|
1028
1029
|
}
|
|
1029
1030
|
writer.write("<!--$-->");
|
|
1030
1031
|
buffer.flushTo(writer);
|
|
@@ -1038,11 +1039,9 @@ async function renderSuspense(props, writer, isSvg = false) {
|
|
|
1038
1039
|
if (fallback) {
|
|
1039
1040
|
const r = renderNode(fallback, writer, isSvg);
|
|
1040
1041
|
if (r && typeof r.then === "function") {
|
|
1041
|
-
const
|
|
1042
|
-
const u = captureUnsuspend();
|
|
1042
|
+
const rctx = captureRenderCtx();
|
|
1043
1043
|
await r;
|
|
1044
|
-
|
|
1045
|
-
restoreUnsuspend(u);
|
|
1044
|
+
restoreRenderCtx(rctx);
|
|
1046
1045
|
}
|
|
1047
1046
|
}
|
|
1048
1047
|
writer.write("<!--/$-->");
|
|
@@ -1079,9 +1078,9 @@ function renderToStream(element, options) {
|
|
|
1079
1078
|
try {
|
|
1080
1079
|
const r = renderNode(element, writer);
|
|
1081
1080
|
if (r && typeof r.then === "function") {
|
|
1082
|
-
const
|
|
1081
|
+
const rctx = captureRenderCtx();
|
|
1083
1082
|
await r;
|
|
1084
|
-
|
|
1083
|
+
restoreRenderCtx(rctx);
|
|
1085
1084
|
}
|
|
1086
1085
|
writer.flush();
|
|
1087
1086
|
controller.close();
|
|
@@ -1108,9 +1107,9 @@ async function renderPreflight(element, options) {
|
|
|
1108
1107
|
NULL_WRITER.lastWasText = false;
|
|
1109
1108
|
const r = renderNode(element, NULL_WRITER);
|
|
1110
1109
|
if (r && typeof r.then === "function") {
|
|
1111
|
-
const
|
|
1110
|
+
const rctx = captureRenderCtx();
|
|
1112
1111
|
await r;
|
|
1113
|
-
|
|
1112
|
+
restoreRenderCtx(rctx);
|
|
1114
1113
|
}
|
|
1115
1114
|
} finally {
|
|
1116
1115
|
swapContextMap(prev);
|
|
@@ -1135,9 +1134,9 @@ async function renderToString(element, options) {
|
|
|
1135
1134
|
resetRenderState(idPrefix);
|
|
1136
1135
|
const r = renderNode(element, writer);
|
|
1137
1136
|
if (r && typeof r.then === "function") {
|
|
1138
|
-
const
|
|
1137
|
+
const rctx = captureRenderCtx();
|
|
1139
1138
|
await r;
|
|
1140
|
-
|
|
1139
|
+
restoreRenderCtx(rctx);
|
|
1141
1140
|
}
|
|
1142
1141
|
return output;
|
|
1143
1142
|
} finally {
|
package/dist/slim-react/index.js
CHANGED
|
@@ -134,7 +134,16 @@ function componentCalledUseId() {
|
|
|
134
134
|
function snapshotContext() {
|
|
135
135
|
const st = s();
|
|
136
136
|
const ctx = st.currentTreeContext;
|
|
137
|
-
|
|
137
|
+
const depth = _treeDepth;
|
|
138
|
+
return {
|
|
139
|
+
tree: { id: ctx.id, overflow: ctx.overflow },
|
|
140
|
+
localId: st.localIdCounter,
|
|
141
|
+
treeDepth: depth,
|
|
142
|
+
// Snapshot the live stack so that popTreeContext reads correct saved values
|
|
143
|
+
// even if another concurrent render's resetRenderState stomped the arrays.
|
|
144
|
+
idStack: _treeIdStack.slice(0, depth),
|
|
145
|
+
ovStack: _treeOvStack.slice(0, depth)
|
|
146
|
+
};
|
|
138
147
|
}
|
|
139
148
|
function restoreContext(snap) {
|
|
140
149
|
const st = s();
|
|
@@ -143,6 +152,10 @@ function restoreContext(snap) {
|
|
|
143
152
|
ctx.overflow = snap.tree.overflow;
|
|
144
153
|
st.localIdCounter = snap.localId;
|
|
145
154
|
_treeDepth = snap.treeDepth;
|
|
155
|
+
for (let i = 0; i < snap.treeDepth; i++) {
|
|
156
|
+
_treeIdStack[i] = snap.idStack[i];
|
|
157
|
+
_treeOvStack[i] = snap.ovStack[i];
|
|
158
|
+
}
|
|
146
159
|
}
|
|
147
160
|
function getTreeId() {
|
|
148
161
|
const { id, overflow } = s().currentTreeContext;
|
|
@@ -256,6 +269,14 @@ function restoreDispatcher(prev) {
|
|
|
256
269
|
}
|
|
257
270
|
|
|
258
271
|
// src/slim-react/render.ts
|
|
272
|
+
function captureRenderCtx() {
|
|
273
|
+
return { m: captureMap(), u: captureUnsuspend(), t: snapshotContext() };
|
|
274
|
+
}
|
|
275
|
+
function restoreRenderCtx(ctx) {
|
|
276
|
+
swapContextMap(ctx.m);
|
|
277
|
+
restoreUnsuspend(ctx.u);
|
|
278
|
+
restoreContext(ctx.t);
|
|
279
|
+
}
|
|
259
280
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
260
281
|
"area",
|
|
261
282
|
"base",
|
|
@@ -699,11 +720,9 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
699
720
|
if (e && typeof e.then === "function") {
|
|
700
721
|
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
701
722
|
patchPromiseStatus(e);
|
|
702
|
-
const
|
|
703
|
-
const u = captureUnsuspend();
|
|
723
|
+
const rctx = captureRenderCtx();
|
|
704
724
|
return e.then(() => {
|
|
705
|
-
|
|
706
|
-
restoreUnsuspend(u);
|
|
725
|
+
restoreRenderCtx(rctx);
|
|
707
726
|
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
708
727
|
});
|
|
709
728
|
}
|
|
@@ -740,17 +759,14 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
740
759
|
};
|
|
741
760
|
const r2 = renderChildren(props.children, writer, isSvg);
|
|
742
761
|
if (r2 && typeof r2.then === "function") {
|
|
743
|
-
const
|
|
744
|
-
const u = captureUnsuspend();
|
|
762
|
+
const rctx = captureRenderCtx();
|
|
745
763
|
return r2.then(
|
|
746
764
|
() => {
|
|
747
|
-
|
|
748
|
-
restoreUnsuspend(u);
|
|
765
|
+
restoreRenderCtx(rctx);
|
|
749
766
|
finish();
|
|
750
767
|
},
|
|
751
768
|
(e) => {
|
|
752
|
-
|
|
753
|
-
restoreUnsuspend(u);
|
|
769
|
+
restoreRenderCtx(rctx);
|
|
754
770
|
finish();
|
|
755
771
|
throw e;
|
|
756
772
|
}
|
|
@@ -779,11 +795,9 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
779
795
|
if (e && typeof e.then === "function") {
|
|
780
796
|
if (_suspenseRetries + 1 >= MAX_COMPONENT_SUSPENSE_RETRIES) throw SUSPENSE_RETRY_LIMIT;
|
|
781
797
|
patchPromiseStatus(e);
|
|
782
|
-
const
|
|
783
|
-
const u = captureUnsuspend();
|
|
798
|
+
const rctx = captureRenderCtx();
|
|
784
799
|
return e.then(() => {
|
|
785
|
-
|
|
786
|
-
restoreUnsuspend(u);
|
|
800
|
+
restoreRenderCtx(rctx);
|
|
787
801
|
return renderComponent(type, props, writer, isSvg, _suspenseRetries + 1);
|
|
788
802
|
});
|
|
789
803
|
}
|
|
@@ -795,30 +809,25 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
795
809
|
savedIdTree = pushTreeContext(1, 0);
|
|
796
810
|
}
|
|
797
811
|
if (result instanceof Promise) {
|
|
798
|
-
const
|
|
799
|
-
const u = captureUnsuspend();
|
|
812
|
+
const rctx = captureRenderCtx();
|
|
800
813
|
return result.then((resolved) => {
|
|
801
|
-
|
|
802
|
-
restoreUnsuspend(u);
|
|
814
|
+
restoreRenderCtx(rctx);
|
|
803
815
|
let asyncSavedIdTree;
|
|
804
816
|
if (componentCalledUseId()) {
|
|
805
817
|
asyncSavedIdTree = pushTreeContext(1, 0);
|
|
806
818
|
}
|
|
807
819
|
const r2 = renderNode(resolved, writer, isSvg);
|
|
808
820
|
if (r2 && typeof r2.then === "function") {
|
|
809
|
-
const
|
|
810
|
-
const u2 = captureUnsuspend();
|
|
821
|
+
const rctx2 = captureRenderCtx();
|
|
811
822
|
return r2.then(
|
|
812
823
|
() => {
|
|
813
|
-
|
|
814
|
-
restoreUnsuspend(u2);
|
|
824
|
+
restoreRenderCtx(rctx2);
|
|
815
825
|
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
816
826
|
popComponentScope(savedScope);
|
|
817
827
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
818
828
|
},
|
|
819
829
|
(e) => {
|
|
820
|
-
|
|
821
|
-
restoreUnsuspend(u2);
|
|
830
|
+
restoreRenderCtx(rctx2);
|
|
822
831
|
if (asyncSavedIdTree !== void 0) popTreeContext(asyncSavedIdTree);
|
|
823
832
|
popComponentScope(savedScope);
|
|
824
833
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
@@ -830,8 +839,7 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
830
839
|
popComponentScope(savedScope);
|
|
831
840
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
832
841
|
}, (e) => {
|
|
833
|
-
|
|
834
|
-
restoreUnsuspend(u);
|
|
842
|
+
restoreRenderCtx(rctx);
|
|
835
843
|
popComponentScope(savedScope);
|
|
836
844
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
837
845
|
throw e;
|
|
@@ -839,19 +847,16 @@ function renderComponent(type, props, writer, isSvg, _suspenseRetries = 0) {
|
|
|
839
847
|
}
|
|
840
848
|
const r = renderNode(result, writer, isSvg);
|
|
841
849
|
if (r && typeof r.then === "function") {
|
|
842
|
-
const
|
|
843
|
-
const u = captureUnsuspend();
|
|
850
|
+
const rctx = captureRenderCtx();
|
|
844
851
|
return r.then(
|
|
845
852
|
() => {
|
|
846
|
-
|
|
847
|
-
restoreUnsuspend(u);
|
|
853
|
+
restoreRenderCtx(rctx);
|
|
848
854
|
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
849
855
|
popComponentScope(savedScope);
|
|
850
856
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
851
857
|
},
|
|
852
858
|
(e) => {
|
|
853
|
-
|
|
854
|
-
restoreUnsuspend(u);
|
|
859
|
+
restoreRenderCtx(rctx);
|
|
855
860
|
if (savedIdTree !== void 0) popTreeContext(savedIdTree);
|
|
856
861
|
popComponentScope(savedScope);
|
|
857
862
|
if (isProvider) popContextValue(ctx, prevCtxValue);
|
|
@@ -876,11 +881,9 @@ function renderChildArrayFrom(children, startIndex, writer, isSvg) {
|
|
|
876
881
|
const savedTree = pushTreeContext(totalChildren, i);
|
|
877
882
|
const r = renderNode(child, writer, isSvg);
|
|
878
883
|
if (r && typeof r.then === "function") {
|
|
879
|
-
const
|
|
880
|
-
const u = captureUnsuspend();
|
|
884
|
+
const rctx = captureRenderCtx();
|
|
881
885
|
return r.then(() => {
|
|
882
|
-
|
|
883
|
-
restoreUnsuspend(u);
|
|
886
|
+
restoreRenderCtx(rctx);
|
|
884
887
|
popTreeContext(savedTree);
|
|
885
888
|
return renderChildArrayFrom(children, i + 1, writer, isSvg);
|
|
886
889
|
});
|
|
@@ -904,11 +907,9 @@ async function renderSuspense(props, writer, isSvg = false) {
|
|
|
904
907
|
try {
|
|
905
908
|
const r = renderNode(children, buffer, isSvg);
|
|
906
909
|
if (r && typeof r.then === "function") {
|
|
907
|
-
const
|
|
908
|
-
const u = captureUnsuspend();
|
|
910
|
+
const rctx = captureRenderCtx();
|
|
909
911
|
await r;
|
|
910
|
-
|
|
911
|
-
restoreUnsuspend(u);
|
|
912
|
+
restoreRenderCtx(rctx);
|
|
912
913
|
}
|
|
913
914
|
writer.write("<!--$-->");
|
|
914
915
|
buffer.flushTo(writer);
|
|
@@ -922,11 +923,9 @@ async function renderSuspense(props, writer, isSvg = false) {
|
|
|
922
923
|
if (fallback) {
|
|
923
924
|
const r = renderNode(fallback, writer, isSvg);
|
|
924
925
|
if (r && typeof r.then === "function") {
|
|
925
|
-
const
|
|
926
|
-
const u = captureUnsuspend();
|
|
926
|
+
const rctx = captureRenderCtx();
|
|
927
927
|
await r;
|
|
928
|
-
|
|
929
|
-
restoreUnsuspend(u);
|
|
928
|
+
restoreRenderCtx(rctx);
|
|
930
929
|
}
|
|
931
930
|
}
|
|
932
931
|
writer.write("<!--/$-->");
|
|
@@ -955,9 +954,9 @@ async function renderToString(element, options) {
|
|
|
955
954
|
resetRenderState(idPrefix);
|
|
956
955
|
const r = renderNode(element, writer);
|
|
957
956
|
if (r && typeof r.then === "function") {
|
|
958
|
-
const
|
|
957
|
+
const rctx = captureRenderCtx();
|
|
959
958
|
await r;
|
|
960
|
-
|
|
959
|
+
restoreRenderCtx(rctx);
|
|
961
960
|
}
|
|
962
961
|
return output;
|
|
963
962
|
} finally {
|
package/dist/ssr-watch.js
CHANGED
|
@@ -265,6 +265,12 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
|
|
|
265
265
|
// changed files, making repeat dev starts significantly faster.
|
|
266
266
|
cache: true,
|
|
267
267
|
externals,
|
|
268
|
+
// externalsPresets.node externalises ALL Node.js built-ins (bare names
|
|
269
|
+
// and the node: prefix) for both static and dynamic imports. This
|
|
270
|
+
// complements the explicit `externals` array: the preset handles the
|
|
271
|
+
// node: URI scheme that rspack cannot resolve as a file, while the
|
|
272
|
+
// array keeps '@emotion/server' as an explicit external.
|
|
273
|
+
...isServerBuild ? { externalsPresets: { node: true } } : {},
|
|
268
274
|
...optimization !== void 0 ? { optimization } : {},
|
|
269
275
|
plugins: [
|
|
270
276
|
!isServerBuild && new rspack.HtmlRspackPlugin({
|
|
@@ -317,7 +323,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
|
|
|
317
323
|
// SSR watcher writing .hadars/index.ssr.js triggers the client compiler
|
|
318
324
|
// and vice versa, causing an infinite rebuild loop.
|
|
319
325
|
watchOptions: {
|
|
320
|
-
ignored: ["**/node_modules/**", "**/.hadars/**"]
|
|
326
|
+
ignored: ["**/node_modules/**", "**/.hadars/**", "/tmp/**"]
|
|
321
327
|
}
|
|
322
328
|
};
|
|
323
329
|
};
|
|
@@ -326,7 +332,7 @@ var compileEntry = async (entry2, opts) => {
|
|
|
326
332
|
if (opts.watch) {
|
|
327
333
|
await new Promise((resolve, reject) => {
|
|
328
334
|
let first = true;
|
|
329
|
-
compiler.watch({ ignored: ["**/node_modules/**", "**/.hadars/**"] }, (err, stats) => {
|
|
335
|
+
compiler.watch({ ignored: ["**/node_modules/**", "**/.hadars/**", "/tmp/**"] }, (err, stats) => {
|
|
330
336
|
if (err) {
|
|
331
337
|
if (first) {
|
|
332
338
|
first = false;
|
|
@@ -359,10 +365,7 @@ var compileEntry = async (entry2, opts) => {
|
|
|
359
365
|
}
|
|
360
366
|
console.log(stats?.toString({
|
|
361
367
|
colors: true,
|
|
362
|
-
|
|
363
|
-
children: true,
|
|
364
|
-
chunks: true,
|
|
365
|
-
chunkModules: true
|
|
368
|
+
preset: "minimal"
|
|
366
369
|
}));
|
|
367
370
|
resolve(stats);
|
|
368
371
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hadars",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Minimal SSR framework for React — rspack, HMR, TypeScript, Bun/Node/Deno",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build:lib": "tsup src/index.tsx src/lambda.ts src/cloudflare.ts src/slim-react/index.ts src/slim-react/jsx-runtime.ts --format esm,cjs --dts --out-dir dist --clean --external '@rspack/*' --external '@rspack/binding'",
|
|
43
43
|
"build:cli": "node build-scripts/build-cli.mjs",
|
|
44
|
-
"build:all": "
|
|
44
|
+
"build:all": "node build-scripts/build-all.mjs",
|
|
45
45
|
"test": "bun test test/render-compare.test.tsx && bun test test/ssr.test.ts",
|
|
46
46
|
"prepare": "npm run build:all",
|
|
47
47
|
"prepublishOnly": "npm run build:all"
|
package/src/build.ts
CHANGED
|
@@ -701,6 +701,14 @@ export const run = async (options: HadarsRuntimeOptions) => {
|
|
|
701
701
|
fs.readFile(pathMod.join(__dirname, StaticPath, 'out.html'), 'utf-8')
|
|
702
702
|
);
|
|
703
703
|
|
|
704
|
+
// Hoist and pre-import the SSR module at startup so the first request does
|
|
705
|
+
// not pay the module parse/eval cost. The file: URL is stable for the life
|
|
706
|
+
// of the process (no cache-busting needed in run mode).
|
|
707
|
+
const componentPath = pathToFileURL(
|
|
708
|
+
pathMod.resolve(__dirname, HadarsFolder, SSR_FILENAME)
|
|
709
|
+
).href;
|
|
710
|
+
const ssrModulePromise = import(componentPath) as Promise<HadarsEntryModule<any>>;
|
|
711
|
+
|
|
704
712
|
const runHandler: CacheFetchHandler = async (req, ctx) => {
|
|
705
713
|
const request = parseRequest(req);
|
|
706
714
|
if (handler) {
|
|
@@ -733,16 +741,12 @@ export const run = async (options: HadarsRuntimeOptions) => {
|
|
|
733
741
|
if (routeRes) return routeRes;
|
|
734
742
|
}
|
|
735
743
|
|
|
736
|
-
const componentPath = pathToFileURL(
|
|
737
|
-
pathMod.resolve(__dirname, HadarsFolder, SSR_FILENAME)
|
|
738
|
-
).href;
|
|
739
|
-
|
|
740
744
|
try {
|
|
741
745
|
const {
|
|
742
746
|
default: Component,
|
|
743
747
|
getInitProps,
|
|
744
748
|
getFinalProps,
|
|
745
|
-
} =
|
|
749
|
+
} = await ssrModulePromise;
|
|
746
750
|
|
|
747
751
|
if (renderPool && request.headers.get('Accept') !== 'application/json') {
|
|
748
752
|
// Worker runs the full lifecycle — no non-serializable objects cross the thread boundary.
|
package/src/lambda.ts
CHANGED
|
@@ -193,20 +193,13 @@ export function createLambdaHandler(options: HadarsOptions, bundled?: LambdaBund
|
|
|
193
193
|
? makePrecontentHtmlGetter(Promise.resolve(bundled.outHtml))
|
|
194
194
|
: makePrecontentHtmlGetter(fs.readFile(pathMod.join(cwd, StaticPath, 'out.html'), 'utf-8'));
|
|
195
195
|
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (!ssrModulePromise) {
|
|
204
|
-
ssrModulePromise = import(
|
|
205
|
-
pathToFileURL(pathMod.resolve(cwd, HadarsFolder, SSR_FILENAME)).href
|
|
206
|
-
) as Promise<HadarsEntryModule<any>>;
|
|
207
|
-
}
|
|
208
|
-
return ssrModulePromise;
|
|
209
|
-
};
|
|
196
|
+
// Start loading the SSR module immediately — during Lambda's init phase this
|
|
197
|
+
// is "free" time not billed against request latency. Lazy loading would
|
|
198
|
+
// push the module parse cost onto the first request.
|
|
199
|
+
const ssrModulePromise: Promise<HadarsEntryModule<any>> = bundled
|
|
200
|
+
? Promise.resolve(bundled.ssrModule)
|
|
201
|
+
: import(pathToFileURL(pathMod.resolve(cwd, HadarsFolder, SSR_FILENAME)).href) as Promise<HadarsEntryModule<any>>;
|
|
202
|
+
const getSsrModule = () => ssrModulePromise;
|
|
210
203
|
|
|
211
204
|
const runHandler = async (req: Request): Promise<Response> => {
|
|
212
205
|
const request = parseRequest(req);
|