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/server.js CHANGED
@@ -128,7 +128,7 @@ function createMemo(compute, options) {
128
128
  }
129
129
  }
130
130
  const ssrSource = options?.ssrSource;
131
- if (ssrSource === "initial" || ssrSource === "client") {
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" || ssrSource === "initial") {
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 === "initial" || options?.ssrSource === "client") {
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) throw new InvalidTopLevelAsyncReadError();
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 collapseFallback = revealGroup ? revealGroup.register(id) : false;
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 together = !!props.together;
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
- collapsedByParent = parentGroup.register(id);
1036
- if (collapsed || together) console.warn("Nested <Reveal> with collapsed/together won't coordinate correctly with renderToString. Use renderToStream for full support.");
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
- if (collapsedByParent) return true;
1045
- return !together && collapsed && count > 1;
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
- collapsedByParent = parentGroup.register(id, {
1076
+ const reg = parentGroup.register(id, {
1062
1077
  onActivate: () => {
1063
- collapsedByParent = false;
1064
- advanceFrontier();
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
- if (!composites.has(keys[frontier])) ctx.revealFragments?.([keys[frontier]]);
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 activate = composites.get(keys[frontier]);
1080
- if (activate) activate();else if (!together && collapsed) ctx.revealFallbacks?.(keys.slice(frontier));
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
- if (options?.onActivate) composites.set(key, options.onActivate);
1090
- if (collapsedByParent) return true;
1091
- return !together && collapsed && keys.length > 1;
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
- if (collapsedByParent) {
1096
- notifyParentIfDone();
1097
- return;
1098
- }
1099
- if (together) {
1100
- if (resolved.size === keys.length) {
1101
- ctx.revealFragments?.(id);
1102
- notifyParentIfDone();
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
- advanceFrontier();
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(() => iterable, options);
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
- if (Array.isArray(res.value)) {
300
- for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
301
- draft.length = res.value.length;
302
- } else {
303
- Object.assign(draft, res.value);
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
- together: () => !!props.together,
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(() => iterable, options);
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
- if (Array.isArray(res.value)) {
299
- for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
300
- draft.length = res.value.length;
301
- } else {
302
- Object.assign(draft, res.value);
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
- together: () => !!props.together,
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.7",
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.7",
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"
@@ -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
- * - **Sequential** (default): boundaries reveal in DOM order as each resolves.
124
- * - **Together** (`together`): all boundaries wait until the group is ready, then reveal at once.
125
- * - **Collapsed** (`collapsed`, sequential only): only the frontier boundary shows its fallback;
126
- * later boundaries produce nothing until their turn.
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
- * <Loading fallback={<Skeleton />}><Posts /></Loading>
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;