solid-js 2.0.0-beta.7 → 2.0.0-beta.8
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/dev.cjs +21 -41
- package/dist/dev.js +21 -41
- package/dist/server.cjs +122 -37
- package/dist/server.js +122 -37
- package/dist/solid.cjs +21 -41
- package/dist/solid.js +21 -41
- package/package.json +2 -2
- package/types/client/flow.d.ts +34 -13
- package/types/client/hydration.d.ts +31 -6
- package/types/jsx-properties.d.ts +2 -5
- package/types/jsx.d.ts +108 -77
- package/types/server/flow.d.ts +40 -7
- package/types/server/hydration.d.ts +18 -1
- package/types/server/signals.d.ts +29 -9
- package/types-cjs/client/flow.d.cts +34 -13
- package/types-cjs/client/hydration.d.cts +31 -6
- package/types-cjs/jsx-properties.d.cts +2 -5
- package/types-cjs/jsx.d.cts +108 -77
- package/types-cjs/server/flow.d.cts +40 -7
- package/types-cjs/server/hydration.d.cts +18 -1
- package/types-cjs/server/signals.d.cts +29 -9
package/dist/server.js
CHANGED
|
@@ -128,7 +128,7 @@ function createMemo(compute, options) {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
const ssrSource = options?.ssrSource;
|
|
131
|
-
if (ssrSource === "
|
|
131
|
+
if (ssrSource === "client") {
|
|
132
132
|
comp.computed = true;
|
|
133
133
|
} else if (!options?.lazy) {
|
|
134
134
|
update();
|
|
@@ -324,7 +324,7 @@ function closeAsyncIterator(iter, value) {
|
|
|
324
324
|
}
|
|
325
325
|
function serverEffect(compute, effectFn, options) {
|
|
326
326
|
const ssrSource = options?.ssrSource;
|
|
327
|
-
if (ssrSource === "client"
|
|
327
|
+
if (ssrSource === "client") {
|
|
328
328
|
createOwner();
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
@@ -405,7 +405,7 @@ function createProjection(fn, initialValue, options) {
|
|
|
405
405
|
const ctx = sharedConfig.context;
|
|
406
406
|
const owner = createOwner();
|
|
407
407
|
const [state] = createStore(initialValue);
|
|
408
|
-
if (options?.ssrSource === "
|
|
408
|
+
if (options?.ssrSource === "client") {
|
|
409
409
|
return state;
|
|
410
410
|
}
|
|
411
411
|
let disposed = false;
|
|
@@ -825,12 +825,6 @@ function ssrHandleError(err) {
|
|
|
825
825
|
}
|
|
826
826
|
throw err;
|
|
827
827
|
}
|
|
828
|
-
class InvalidTopLevelAsyncReadError extends Error {
|
|
829
|
-
constructor() {
|
|
830
|
-
super("Async values must be read within a tracking scope (JSX, a memo, or an effect's compute function).");
|
|
831
|
-
this.name = "InvalidTopLevelAsyncReadError";
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
828
|
function createLoadingBoundary(fn, fallback, options) {
|
|
835
829
|
const currentCtx = sharedConfig.context;
|
|
836
830
|
if (!currentCtx) {
|
|
@@ -845,6 +839,7 @@ function createLoadingBoundary(fn, fallback, options) {
|
|
|
845
839
|
o.id = id + "00";
|
|
846
840
|
let done;
|
|
847
841
|
let handledRenderError;
|
|
842
|
+
let retryPromise;
|
|
848
843
|
let serializeBuffer = [];
|
|
849
844
|
const bufferedCtx = Object.create(ctx);
|
|
850
845
|
bufferedCtx.serialize = (id, value, deferStream) => {
|
|
@@ -888,21 +883,26 @@ function createLoadingBoundary(fn, fallback, options) {
|
|
|
888
883
|
function runDiscovery() {
|
|
889
884
|
o.dispose(false);
|
|
890
885
|
serializeBuffer = [];
|
|
886
|
+
retryPromise = undefined;
|
|
891
887
|
return runLoadingPhase(() => {
|
|
892
888
|
try {
|
|
893
889
|
return ctx.resolve(fn());
|
|
894
890
|
} catch (err) {
|
|
895
|
-
if (err instanceof NotReadyError)
|
|
891
|
+
if (err instanceof NotReadyError) {
|
|
892
|
+
retryPromise = err.source;
|
|
893
|
+
return undefined;
|
|
894
|
+
}
|
|
896
895
|
throw err;
|
|
897
896
|
}
|
|
898
897
|
});
|
|
899
898
|
}
|
|
900
899
|
let ret = runDiscovery();
|
|
901
|
-
if (!ret?.p?.length) {
|
|
900
|
+
if (!retryPromise && !ret?.p?.length) {
|
|
902
901
|
commitBoundaryState();
|
|
903
902
|
return () => ret;
|
|
904
903
|
}
|
|
905
|
-
const
|
|
904
|
+
const regResult = revealGroup ? revealGroup.register(id) : null;
|
|
905
|
+
const collapseFallback = regResult?.collapseFallback ?? false;
|
|
906
906
|
if (collapseFallback && !ctx.async) {
|
|
907
907
|
commitBoundaryState();
|
|
908
908
|
ctx.serialize(id, "$$f");
|
|
@@ -923,6 +923,10 @@ function createLoadingBoundary(fn, fallback, options) {
|
|
|
923
923
|
done = ctx.registerFragment(id, regOpts);
|
|
924
924
|
(async () => {
|
|
925
925
|
try {
|
|
926
|
+
while (retryPromise) {
|
|
927
|
+
await retryPromise.catch(() => {});
|
|
928
|
+
ret = runDiscovery();
|
|
929
|
+
}
|
|
926
930
|
commitBoundaryState();
|
|
927
931
|
while (ret.p.length) {
|
|
928
932
|
await Promise.all(ret.p).catch(() => {});
|
|
@@ -1025,15 +1029,16 @@ function Loading(props) {
|
|
|
1025
1029
|
function Reveal(props) {
|
|
1026
1030
|
const o = createOwner();
|
|
1027
1031
|
const id = o.id;
|
|
1028
|
-
const
|
|
1029
|
-
const collapsed = !!props.collapsed;
|
|
1032
|
+
const order = props.order ?? "sequential";
|
|
1033
|
+
const collapsed = order === "sequential" && !!props.collapsed;
|
|
1030
1034
|
if (!sharedConfig.context?.async) {
|
|
1031
1035
|
const parent = getOwner();
|
|
1032
1036
|
const parentGroup = parent ? runWithOwner(parent, () => getContext(RevealGroupContext)) : null;
|
|
1033
1037
|
let collapsedByParent = false;
|
|
1034
1038
|
if (parentGroup) {
|
|
1035
|
-
|
|
1036
|
-
|
|
1039
|
+
const reg = parentGroup.register(id);
|
|
1040
|
+
collapsedByParent = reg.collapseFallback;
|
|
1041
|
+
if (order === "together" || collapsed) console.warn("Nested <Reveal> with collapsed/together won't coordinate correctly with renderToString. Use renderToStream for full support.");
|
|
1037
1042
|
}
|
|
1038
1043
|
let count = 0;
|
|
1039
1044
|
return runWithOwner(o, () => {
|
|
@@ -1041,8 +1046,11 @@ function Reveal(props) {
|
|
|
1041
1046
|
id,
|
|
1042
1047
|
register(_key) {
|
|
1043
1048
|
count++;
|
|
1044
|
-
|
|
1045
|
-
return
|
|
1049
|
+
const collapseFallback = collapsedByParent || order === "sequential" && collapsed && count > 1;
|
|
1050
|
+
return {
|
|
1051
|
+
collapseFallback,
|
|
1052
|
+
held: false
|
|
1053
|
+
};
|
|
1046
1054
|
},
|
|
1047
1055
|
onResolved() {}
|
|
1048
1056
|
});
|
|
@@ -1052,58 +1060,129 @@ function Reveal(props) {
|
|
|
1052
1060
|
const ctx = sharedConfig.context;
|
|
1053
1061
|
const keys = [];
|
|
1054
1062
|
const resolved = new Set();
|
|
1063
|
+
const minimallyResolved = new Set();
|
|
1055
1064
|
const composites = new Map();
|
|
1065
|
+
const activated = new Set();
|
|
1066
|
+
const stash = [];
|
|
1067
|
+
const collapsedLeafKeys = [];
|
|
1056
1068
|
let frontier = 0;
|
|
1069
|
+
let heldByParent = false;
|
|
1070
|
+
let collapsedByParent = false;
|
|
1071
|
+
let selfMinimallyResolved = false;
|
|
1072
|
+
let notifiedParentDone = false;
|
|
1057
1073
|
const parent = getOwner();
|
|
1058
1074
|
const parentGroup = parent ? runWithOwner(parent, () => getContext(RevealGroupContext)) : null;
|
|
1059
|
-
let collapsedByParent = false;
|
|
1060
1075
|
if (parentGroup) {
|
|
1061
|
-
|
|
1076
|
+
const reg = parentGroup.register(id, {
|
|
1062
1077
|
onActivate: () => {
|
|
1063
|
-
|
|
1064
|
-
|
|
1078
|
+
if (!heldByParent) return;
|
|
1079
|
+
heldByParent = false;
|
|
1080
|
+
if (collapsedByParent) {
|
|
1081
|
+
collapsedByParent = false;
|
|
1082
|
+
if (collapsedLeafKeys.length) {
|
|
1083
|
+
ctx.revealFallbacks?.([...collapsedLeafKeys]);
|
|
1084
|
+
collapsedLeafKeys.length = 0;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
if (order === "sequential") advanceFrontier();else if (order === "together") checkTogetherRelease();else naturalRelease();
|
|
1065
1088
|
}
|
|
1066
1089
|
});
|
|
1090
|
+
collapsedByParent = reg.collapseFallback;
|
|
1091
|
+
heldByParent = reg.held;
|
|
1067
1092
|
}
|
|
1068
1093
|
function notifyParentIfDone() {
|
|
1094
|
+
if (notifiedParentDone) return;
|
|
1069
1095
|
if (parentGroup && resolved.size === keys.length) {
|
|
1096
|
+
notifiedParentDone = true;
|
|
1070
1097
|
parentGroup.onResolved(id);
|
|
1071
1098
|
}
|
|
1072
1099
|
}
|
|
1100
|
+
function activateComposite(key) {
|
|
1101
|
+
if (activated.has(key)) return;
|
|
1102
|
+
activated.add(key);
|
|
1103
|
+
composites.get(key)();
|
|
1104
|
+
}
|
|
1105
|
+
function updateSelfMinimallyResolved() {
|
|
1106
|
+
if (selfMinimallyResolved) return;
|
|
1107
|
+
if (keys.length === 0) selfMinimallyResolved = true;else if (order === "together") selfMinimallyResolved = minimallyResolved.size === keys.length;else if (order === "sequential") selfMinimallyResolved = minimallyResolved.has(keys[0]);
|
|
1108
|
+
else selfMinimallyResolved = resolved.size > 0;
|
|
1109
|
+
if (selfMinimallyResolved) parentGroup?.onMinimallyResolved?.(id);
|
|
1110
|
+
}
|
|
1073
1111
|
function advanceFrontier() {
|
|
1112
|
+
if (heldByParent) return;
|
|
1074
1113
|
while (frontier < keys.length && resolved.has(keys[frontier])) {
|
|
1075
|
-
|
|
1114
|
+
const k = keys[frontier];
|
|
1115
|
+
if (composites.has(k)) activateComposite(k);else ctx.revealFragments?.([k]);
|
|
1076
1116
|
frontier++;
|
|
1077
1117
|
}
|
|
1078
1118
|
if (frontier < keys.length) {
|
|
1079
|
-
const
|
|
1080
|
-
if (
|
|
1119
|
+
const k = keys[frontier];
|
|
1120
|
+
if (composites.has(k)) activateComposite(k);else if (order === "sequential" && collapsed) ctx.revealFallbacks?.([k]);
|
|
1081
1121
|
}
|
|
1082
1122
|
notifyParentIfDone();
|
|
1083
1123
|
}
|
|
1124
|
+
function checkTogetherRelease() {
|
|
1125
|
+
if (order !== "together" || heldByParent) return;
|
|
1126
|
+
if (minimallyResolved.size < keys.length) return;
|
|
1127
|
+
if (stash.length) {
|
|
1128
|
+
ctx.revealFragments?.([...stash]);
|
|
1129
|
+
stash.length = 0;
|
|
1130
|
+
}
|
|
1131
|
+
composites.forEach((_, key) => activateComposite(key));
|
|
1132
|
+
notifyParentIfDone();
|
|
1133
|
+
}
|
|
1134
|
+
function naturalRelease() {
|
|
1135
|
+
if (stash.length) {
|
|
1136
|
+
ctx.revealFragments?.([...stash]);
|
|
1137
|
+
stash.length = 0;
|
|
1138
|
+
}
|
|
1139
|
+
composites.forEach((_, key) => activateComposite(key));
|
|
1140
|
+
notifyParentIfDone();
|
|
1141
|
+
}
|
|
1084
1142
|
return runWithOwner(o, () => {
|
|
1085
1143
|
setContext(RevealGroupContext, {
|
|
1086
1144
|
id,
|
|
1087
1145
|
register(key, options) {
|
|
1088
1146
|
keys.push(key);
|
|
1089
|
-
|
|
1090
|
-
if (
|
|
1091
|
-
|
|
1147
|
+
const isComposite = !!options?.onActivate;
|
|
1148
|
+
if (isComposite) composites.set(key, options.onActivate);
|
|
1149
|
+
const selfCollapse = order === "sequential" && collapsed && keys.length > 1;
|
|
1150
|
+
const collapseFallback = collapsedByParent || selfCollapse;
|
|
1151
|
+
if (collapseFallback && !isComposite) collapsedLeafKeys.push(key);
|
|
1152
|
+
let held = heldByParent;
|
|
1153
|
+
if (!held) {
|
|
1154
|
+
if (order === "together") held = true;else if (order === "sequential" && keys.length > 1) held = true;
|
|
1155
|
+
}
|
|
1156
|
+
return {
|
|
1157
|
+
collapseFallback,
|
|
1158
|
+
held
|
|
1159
|
+
};
|
|
1092
1160
|
},
|
|
1093
1161
|
onResolved(key) {
|
|
1094
1162
|
resolved.add(key);
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1163
|
+
const isLeaf = !composites.has(key);
|
|
1164
|
+
if (isLeaf) {
|
|
1165
|
+
if (order === "together") {
|
|
1166
|
+
stash.push(key);
|
|
1167
|
+
} else if (order === "natural" && heldByParent) {
|
|
1168
|
+
stash.push(key);
|
|
1169
|
+
} else if (order === "natural") {
|
|
1170
|
+
ctx.revealFragments?.([key]);
|
|
1103
1171
|
}
|
|
1172
|
+
markMinimallyResolved(key);
|
|
1173
|
+
if (order === "sequential" && !heldByParent) advanceFrontier();
|
|
1174
|
+
if (order === "natural") updateSelfMinimallyResolved();
|
|
1104
1175
|
} else {
|
|
1105
|
-
|
|
1176
|
+
if (!heldByParent) {
|
|
1177
|
+
if (order === "sequential") advanceFrontier();else if (order === "natural") activateComposite(key);
|
|
1178
|
+
}
|
|
1179
|
+
if (order === "together") checkTogetherRelease();
|
|
1180
|
+
if (order === "natural") updateSelfMinimallyResolved();
|
|
1106
1181
|
}
|
|
1182
|
+
notifyParentIfDone();
|
|
1183
|
+
},
|
|
1184
|
+
onMinimallyResolved(key) {
|
|
1185
|
+
markMinimallyResolved(key);
|
|
1107
1186
|
}
|
|
1108
1187
|
});
|
|
1109
1188
|
const result = props.children;
|
|
@@ -1112,6 +1191,12 @@ function Reveal(props) {
|
|
|
1112
1191
|
}
|
|
1113
1192
|
return result;
|
|
1114
1193
|
});
|
|
1194
|
+
function markMinimallyResolved(key) {
|
|
1195
|
+
if (minimallyResolved.has(key)) return;
|
|
1196
|
+
minimallyResolved.add(key);
|
|
1197
|
+
updateSelfMinimallyResolved();
|
|
1198
|
+
if (order === "together") checkTogetherRelease();
|
|
1199
|
+
}
|
|
1115
1200
|
}
|
|
1116
1201
|
|
|
1117
1202
|
const DEV = undefined;
|
package/dist/solid.cjs
CHANGED
|
@@ -277,9 +277,12 @@ function hydrateSignalFromAsyncIterable(coreFn, compute, options) {
|
|
|
277
277
|
return it;
|
|
278
278
|
}
|
|
279
279
|
};
|
|
280
|
-
return coreFn(
|
|
280
|
+
return coreFn(prev => {
|
|
281
|
+
subFetch(compute, prev);
|
|
282
|
+
return iterable;
|
|
283
|
+
}, options);
|
|
281
284
|
}
|
|
282
|
-
function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
285
|
+
function hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options) {
|
|
283
286
|
const parent = signals.getOwner();
|
|
284
287
|
const expectedId = signals.peekNextChildId(parent);
|
|
285
288
|
if (!sharedConfig.has(expectedId)) return null;
|
|
@@ -289,6 +292,10 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
289
292
|
let isFirst = true;
|
|
290
293
|
let buffered = null;
|
|
291
294
|
return coreFn(draft => {
|
|
295
|
+
const {
|
|
296
|
+
proxy
|
|
297
|
+
} = createShadowDraft(draft);
|
|
298
|
+
subFetch(fn, proxy);
|
|
292
299
|
const process = res => {
|
|
293
300
|
if (res.done) return {
|
|
294
301
|
done: true,
|
|
@@ -296,11 +303,16 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
296
303
|
};
|
|
297
304
|
if (isFirst) {
|
|
298
305
|
isFirst = false;
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
306
|
+
signals.setSnapshotCapture(false);
|
|
307
|
+
try {
|
|
308
|
+
if (Array.isArray(res.value)) {
|
|
309
|
+
for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
|
|
310
|
+
draft.length = res.value.length;
|
|
311
|
+
} else {
|
|
312
|
+
Object.assign(draft, res.value);
|
|
313
|
+
}
|
|
314
|
+
} finally {
|
|
315
|
+
signals.setSnapshotCapture(true);
|
|
304
316
|
}
|
|
305
317
|
} else {
|
|
306
318
|
applyPatches(draft, res.value);
|
|
@@ -369,13 +381,6 @@ function hydratedCreateMemo(compute, options) {
|
|
|
369
381
|
setHydrated(true);
|
|
370
382
|
return memo;
|
|
371
383
|
}
|
|
372
|
-
if (ssrSource === "initial") {
|
|
373
|
-
return signals.createMemo(prev => {
|
|
374
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
375
|
-
subFetch(compute, prev);
|
|
376
|
-
return prev;
|
|
377
|
-
}, options);
|
|
378
|
-
}
|
|
379
384
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createMemo, compute, options);
|
|
380
385
|
if (aiResult !== null) return aiResult;
|
|
381
386
|
return signals.createMemo(prev => readSerializedOrCompute(compute, prev), options);
|
|
@@ -395,13 +400,6 @@ function hydratedCreateSignal(fn, second) {
|
|
|
395
400
|
setHydrated(true);
|
|
396
401
|
return sig;
|
|
397
402
|
}
|
|
398
|
-
if (ssrSource === "initial") {
|
|
399
|
-
return signals.createSignal(prev => {
|
|
400
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
401
|
-
subFetch(fn, prev);
|
|
402
|
-
return prev;
|
|
403
|
-
}, second);
|
|
404
|
-
}
|
|
405
403
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createSignal, fn, second);
|
|
406
404
|
if (aiResult !== null) return aiResult;
|
|
407
405
|
return signals.createSignal(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -441,13 +439,6 @@ function hydratedCreateOptimistic(fn, second) {
|
|
|
441
439
|
setHydrated(true);
|
|
442
440
|
return sig;
|
|
443
441
|
}
|
|
444
|
-
if (ssrSource === "initial") {
|
|
445
|
-
return signals.createOptimistic(prev => {
|
|
446
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
447
|
-
subFetch(fn, prev);
|
|
448
|
-
return prev;
|
|
449
|
-
}, second);
|
|
450
|
-
}
|
|
451
442
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createOptimistic, fn, second);
|
|
452
443
|
if (aiResult !== null) return aiResult;
|
|
453
444
|
return signals.createOptimistic(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -491,7 +482,7 @@ function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) {
|
|
|
491
482
|
setHydrated(true);
|
|
492
483
|
return result;
|
|
493
484
|
}
|
|
494
|
-
const aiResult = hydrateStoreFromAsyncIterable(coreFn, initialValue, options);
|
|
485
|
+
const aiResult = hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options);
|
|
495
486
|
if (aiResult !== null) return aiResult;
|
|
496
487
|
return coreFn(wrapStoreFn(fn), initialValue, options);
|
|
497
488
|
}
|
|
@@ -499,21 +490,18 @@ function hydratedCreateStore(first, second, third) {
|
|
|
499
490
|
if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createStore(first, second, third);
|
|
500
491
|
markTopLevelSnapshotScope();
|
|
501
492
|
const ssrSource = third?.ssrSource;
|
|
502
|
-
if (ssrSource === "initial") return signals.createStore(second ?? {});
|
|
503
493
|
return hydrateStoreLikeFn(signals.createStore, first, second ?? {}, third, ssrSource);
|
|
504
494
|
}
|
|
505
495
|
function hydratedCreateOptimisticStore(first, second, third) {
|
|
506
496
|
if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createOptimisticStore(first, second, third);
|
|
507
497
|
markTopLevelSnapshotScope();
|
|
508
498
|
const ssrSource = third?.ssrSource;
|
|
509
|
-
if (ssrSource === "initial") return signals.createOptimisticStore(second ?? {});
|
|
510
499
|
return hydrateStoreLikeFn(signals.createOptimisticStore, first, second ?? {}, third, ssrSource);
|
|
511
500
|
}
|
|
512
501
|
function hydratedCreateProjection(fn, initialValue, options) {
|
|
513
502
|
if (!sharedConfig.hydrating) return signals.createProjection(fn, initialValue, options);
|
|
514
503
|
markTopLevelSnapshotScope();
|
|
515
504
|
const ssrSource = options?.ssrSource;
|
|
516
|
-
if (ssrSource === "initial") return signals.createProjection(draft => draft, initialValue, options);
|
|
517
505
|
return hydrateStoreLikeFn(signals.createProjection, fn, initialValue, options, ssrSource);
|
|
518
506
|
}
|
|
519
507
|
function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
@@ -535,14 +523,6 @@ function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
|
535
523
|
setHydrated(true);
|
|
536
524
|
return;
|
|
537
525
|
}
|
|
538
|
-
if (ssrSource === "initial") {
|
|
539
|
-
coreFn(prev => {
|
|
540
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
541
|
-
subFetch(compute, prev);
|
|
542
|
-
return prev;
|
|
543
|
-
}, effectFn, options);
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
526
|
markTopLevelSnapshotScope();
|
|
547
527
|
coreFn(prev => readSerializedOrCompute(compute, prev), effectFn, options);
|
|
548
528
|
}
|
|
@@ -854,7 +834,7 @@ function Loading(props) {
|
|
|
854
834
|
}
|
|
855
835
|
function Reveal(props) {
|
|
856
836
|
return signals.createRevealOrder(() => props.children, {
|
|
857
|
-
|
|
837
|
+
order: () => props.order ?? "sequential",
|
|
858
838
|
collapsed: () => !!props.collapsed
|
|
859
839
|
});
|
|
860
840
|
}
|
package/dist/solid.js
CHANGED
|
@@ -276,9 +276,12 @@ function hydrateSignalFromAsyncIterable(coreFn, compute, options) {
|
|
|
276
276
|
return it;
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
|
-
return coreFn(
|
|
279
|
+
return coreFn(prev => {
|
|
280
|
+
subFetch(compute, prev);
|
|
281
|
+
return iterable;
|
|
282
|
+
}, options);
|
|
280
283
|
}
|
|
281
|
-
function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
284
|
+
function hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options) {
|
|
282
285
|
const parent = getOwner();
|
|
283
286
|
const expectedId = peekNextChildId(parent);
|
|
284
287
|
if (!sharedConfig.has(expectedId)) return null;
|
|
@@ -288,6 +291,10 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
288
291
|
let isFirst = true;
|
|
289
292
|
let buffered = null;
|
|
290
293
|
return coreFn(draft => {
|
|
294
|
+
const {
|
|
295
|
+
proxy
|
|
296
|
+
} = createShadowDraft(draft);
|
|
297
|
+
subFetch(fn, proxy);
|
|
291
298
|
const process = res => {
|
|
292
299
|
if (res.done) return {
|
|
293
300
|
done: true,
|
|
@@ -295,11 +302,16 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
295
302
|
};
|
|
296
303
|
if (isFirst) {
|
|
297
304
|
isFirst = false;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
setSnapshotCapture(false);
|
|
306
|
+
try {
|
|
307
|
+
if (Array.isArray(res.value)) {
|
|
308
|
+
for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
|
|
309
|
+
draft.length = res.value.length;
|
|
310
|
+
} else {
|
|
311
|
+
Object.assign(draft, res.value);
|
|
312
|
+
}
|
|
313
|
+
} finally {
|
|
314
|
+
setSnapshotCapture(true);
|
|
303
315
|
}
|
|
304
316
|
} else {
|
|
305
317
|
applyPatches(draft, res.value);
|
|
@@ -368,13 +380,6 @@ function hydratedCreateMemo(compute, options) {
|
|
|
368
380
|
setHydrated(true);
|
|
369
381
|
return memo;
|
|
370
382
|
}
|
|
371
|
-
if (ssrSource === "initial") {
|
|
372
|
-
return createMemo$1(prev => {
|
|
373
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
374
|
-
subFetch(compute, prev);
|
|
375
|
-
return prev;
|
|
376
|
-
}, options);
|
|
377
|
-
}
|
|
378
383
|
const aiResult = hydrateSignalFromAsyncIterable(createMemo$1, compute, options);
|
|
379
384
|
if (aiResult !== null) return aiResult;
|
|
380
385
|
return createMemo$1(prev => readSerializedOrCompute(compute, prev), options);
|
|
@@ -394,13 +399,6 @@ function hydratedCreateSignal(fn, second) {
|
|
|
394
399
|
setHydrated(true);
|
|
395
400
|
return sig;
|
|
396
401
|
}
|
|
397
|
-
if (ssrSource === "initial") {
|
|
398
|
-
return createSignal$1(prev => {
|
|
399
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
400
|
-
subFetch(fn, prev);
|
|
401
|
-
return prev;
|
|
402
|
-
}, second);
|
|
403
|
-
}
|
|
404
402
|
const aiResult = hydrateSignalFromAsyncIterable(createSignal$1, fn, second);
|
|
405
403
|
if (aiResult !== null) return aiResult;
|
|
406
404
|
return createSignal$1(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -440,13 +438,6 @@ function hydratedCreateOptimistic(fn, second) {
|
|
|
440
438
|
setHydrated(true);
|
|
441
439
|
return sig;
|
|
442
440
|
}
|
|
443
|
-
if (ssrSource === "initial") {
|
|
444
|
-
return createOptimistic$1(prev => {
|
|
445
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
446
|
-
subFetch(fn, prev);
|
|
447
|
-
return prev;
|
|
448
|
-
}, second);
|
|
449
|
-
}
|
|
450
441
|
const aiResult = hydrateSignalFromAsyncIterable(createOptimistic$1, fn, second);
|
|
451
442
|
if (aiResult !== null) return aiResult;
|
|
452
443
|
return createOptimistic$1(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -490,7 +481,7 @@ function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) {
|
|
|
490
481
|
setHydrated(true);
|
|
491
482
|
return result;
|
|
492
483
|
}
|
|
493
|
-
const aiResult = hydrateStoreFromAsyncIterable(coreFn, initialValue, options);
|
|
484
|
+
const aiResult = hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options);
|
|
494
485
|
if (aiResult !== null) return aiResult;
|
|
495
486
|
return coreFn(wrapStoreFn(fn), initialValue, options);
|
|
496
487
|
}
|
|
@@ -498,21 +489,18 @@ function hydratedCreateStore(first, second, third) {
|
|
|
498
489
|
if (typeof first !== "function" || !sharedConfig.hydrating) return createStore$1(first, second, third);
|
|
499
490
|
markTopLevelSnapshotScope();
|
|
500
491
|
const ssrSource = third?.ssrSource;
|
|
501
|
-
if (ssrSource === "initial") return createStore$1(second ?? {});
|
|
502
492
|
return hydrateStoreLikeFn(createStore$1, first, second ?? {}, third, ssrSource);
|
|
503
493
|
}
|
|
504
494
|
function hydratedCreateOptimisticStore(first, second, third) {
|
|
505
495
|
if (typeof first !== "function" || !sharedConfig.hydrating) return createOptimisticStore$1(first, second, third);
|
|
506
496
|
markTopLevelSnapshotScope();
|
|
507
497
|
const ssrSource = third?.ssrSource;
|
|
508
|
-
if (ssrSource === "initial") return createOptimisticStore$1(second ?? {});
|
|
509
498
|
return hydrateStoreLikeFn(createOptimisticStore$1, first, second ?? {}, third, ssrSource);
|
|
510
499
|
}
|
|
511
500
|
function hydratedCreateProjection(fn, initialValue, options) {
|
|
512
501
|
if (!sharedConfig.hydrating) return createProjection$1(fn, initialValue, options);
|
|
513
502
|
markTopLevelSnapshotScope();
|
|
514
503
|
const ssrSource = options?.ssrSource;
|
|
515
|
-
if (ssrSource === "initial") return createProjection$1(draft => draft, initialValue, options);
|
|
516
504
|
return hydrateStoreLikeFn(createProjection$1, fn, initialValue, options, ssrSource);
|
|
517
505
|
}
|
|
518
506
|
function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
@@ -534,14 +522,6 @@ function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
|
534
522
|
setHydrated(true);
|
|
535
523
|
return;
|
|
536
524
|
}
|
|
537
|
-
if (ssrSource === "initial") {
|
|
538
|
-
coreFn(prev => {
|
|
539
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
540
|
-
subFetch(compute, prev);
|
|
541
|
-
return prev;
|
|
542
|
-
}, effectFn, options);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
525
|
markTopLevelSnapshotScope();
|
|
546
526
|
coreFn(prev => readSerializedOrCompute(compute, prev), effectFn, options);
|
|
547
527
|
}
|
|
@@ -853,7 +833,7 @@ function Loading(props) {
|
|
|
853
833
|
}
|
|
854
834
|
function Reveal(props) {
|
|
855
835
|
return createRevealOrder(() => props.children, {
|
|
856
|
-
|
|
836
|
+
order: () => props.order ?? "sequential",
|
|
857
837
|
collapsed: () => !!props.collapsed
|
|
858
838
|
});
|
|
859
839
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-js",
|
|
3
3
|
"description": "A declarative JavaScript library for building user interfaces.",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.8",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"performance"
|
|
127
127
|
],
|
|
128
128
|
"dependencies": {
|
|
129
|
-
"@solidjs/signals": "^2.0.0-beta.
|
|
129
|
+
"@solidjs/signals": "^2.0.0-beta.8",
|
|
130
130
|
"csstype": "^3.1.0",
|
|
131
131
|
"seroval": "~1.5.0",
|
|
132
132
|
"seroval-plugins": "~1.5.0"
|
package/types/client/flow.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Accessor } from "@solidjs/signals";
|
|
1
|
+
import type { Accessor, RevealOrder } from "@solidjs/signals";
|
|
2
|
+
export type { RevealOrder };
|
|
2
3
|
import type { JSX } from "../jsx.js";
|
|
3
4
|
type NonZeroParams<T extends (...args: any[]) => any> = Parameters<T>["length"] extends 0 ? never : T;
|
|
4
5
|
type ConditionalRenderCallback<T> = (item: Accessor<NonNullable<T>>) => JSX.Element;
|
|
@@ -117,26 +118,46 @@ export declare function Loading(props: {
|
|
|
117
118
|
on?: any;
|
|
118
119
|
children: JSX.Element;
|
|
119
120
|
}): JSX.Element;
|
|
121
|
+
export type RevealProps = {
|
|
122
|
+
order?: RevealOrder;
|
|
123
|
+
collapsed?: boolean;
|
|
124
|
+
children: JSX.Element;
|
|
125
|
+
};
|
|
120
126
|
/**
|
|
121
127
|
* Coordinates the reveal timing of sibling `<Loading>` boundaries.
|
|
122
128
|
*
|
|
123
|
-
*
|
|
124
|
-
* -
|
|
125
|
-
*
|
|
126
|
-
*
|
|
129
|
+
* The `order` prop picks the reveal policy:
|
|
130
|
+
* - `"sequential"` (default) — boundaries reveal in registration order; later boundaries
|
|
131
|
+
* stay on their fallback until earlier ones resolve.
|
|
132
|
+
* - `"together"` — every direct slot stays on its fallback until the whole group is
|
|
133
|
+
* "minimally ready" (every direct slot has its own first visible content available),
|
|
134
|
+
* then the group releases in one cohesive reveal.
|
|
135
|
+
* - `"natural"` — each boundary reveals as its own data resolves. At the top level
|
|
136
|
+
* this is equivalent to omitting `<Reveal>`; the mode exists for nesting, where
|
|
137
|
+
* the group registers as a single composite slot in an enclosing `<Reveal>`.
|
|
138
|
+
*
|
|
139
|
+
* The `collapsed` prop is only consulted when `order="sequential"` (the default);
|
|
140
|
+
* it is ignored under `"together"` and `"natural"`. When set, tail boundaries past
|
|
141
|
+
* the frontier suppress their own fallback output.
|
|
142
|
+
*
|
|
143
|
+
* Nested `<Reveal>` groups compose: the inner group is one slot in the outer order
|
|
144
|
+
* and is held on its fallbacks until the outer releases the slot. Once released, the
|
|
145
|
+
* inner group runs its own `order` locally over whatever is still pending. There is
|
|
146
|
+
* no escape hatch — nesting under an outer group means participating in its ordering.
|
|
147
|
+
* See `documentation/solid-2.0/03-control-flow.md` for the full nesting matrix and the
|
|
148
|
+
* "minimally ready" definition per order.
|
|
127
149
|
*
|
|
128
150
|
* ```typescript
|
|
129
|
-
* <Reveal>
|
|
151
|
+
* <Reveal order="sequential">
|
|
130
152
|
* <Loading fallback={<Skeleton />}><ProfileHeader /></Loading>
|
|
131
|
-
* <
|
|
153
|
+
* <Reveal order="natural">
|
|
154
|
+
* <Loading fallback={<Skeleton />}><PostA /></Loading>
|
|
155
|
+
* <Loading fallback={<Skeleton />}><PostB /></Loading>
|
|
156
|
+
* </Reveal>
|
|
157
|
+
* <Loading fallback={<Skeleton />}><Comments /></Loading>
|
|
132
158
|
* </Reveal>
|
|
133
159
|
* ```
|
|
134
160
|
*
|
|
135
161
|
* @description https://docs.solidjs.com/reference/components/reveal
|
|
136
162
|
*/
|
|
137
|
-
export declare function Reveal(props:
|
|
138
|
-
together?: boolean;
|
|
139
|
-
collapsed?: boolean;
|
|
140
|
-
children: JSX.Element;
|
|
141
|
-
}): JSX.Element;
|
|
142
|
-
export {};
|
|
163
|
+
export declare function Reveal(props: RevealProps): JSX.Element;
|