solid-js 2.0.0-beta.5 → 2.0.0-beta.7

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.cjs CHANGED
@@ -28,25 +28,82 @@ function runWithObserver(comp, fn) {
28
28
  function getObserver() {
29
29
  return Observer;
30
30
  }
31
- function createSignal(first, second, third) {
31
+ function createDeferredPromise() {
32
+ let settled = false;
33
+ let resolvePromise;
34
+ let rejectPromise;
35
+ const promise = new Promise((resolve, reject) => {
36
+ resolvePromise = resolve;
37
+ rejectPromise = reject;
38
+ });
39
+ return {
40
+ promise,
41
+ resolve(value) {
42
+ if (settled) return;
43
+ settled = true;
44
+ promise.s = 1;
45
+ promise.v = value;
46
+ resolvePromise(value);
47
+ },
48
+ reject(error) {
49
+ if (settled) return;
50
+ settled = true;
51
+ promise.s = 2;
52
+ promise.v = error;
53
+ rejectPromise(error);
54
+ }
55
+ };
56
+ }
57
+ function subscribePendingRetry(error, retry) {
58
+ if (!(error instanceof signals.NotReadyError)) return false;
59
+ error.source?.then(() => retry(), () => retry());
60
+ return true;
61
+ }
62
+ function settleServerAsync(initial, rerun, deferred, onSuccess, onError, isDisposed) {
63
+ let first = true;
64
+ const attempt = () => {
65
+ if (isDisposed()) return;
66
+ let current;
67
+ try {
68
+ current = first ? initial : rerun();
69
+ first = false;
70
+ } catch (error) {
71
+ if (subscribePendingRetry(error, attempt)) return;
72
+ onError(error);
73
+ deferred.reject(error);
74
+ return;
75
+ }
76
+ Promise.resolve(current).then(value => {
77
+ if (isDisposed()) return;
78
+ deferred.resolve(onSuccess(value));
79
+ }, error => {
80
+ if (isDisposed()) return;
81
+ if (subscribePendingRetry(error, attempt)) return;
82
+ onError(error);
83
+ deferred.reject(error);
84
+ });
85
+ };
86
+ attempt();
87
+ }
88
+ function createSignal(first, second) {
32
89
  if (typeof first === "function") {
33
- const opts = third?.deferStream || third?.ssrSource ? {
34
- deferStream: third?.deferStream,
35
- ssrSource: third?.ssrSource
90
+ const opts = second?.deferStream || second?.ssrSource ? {
91
+ deferStream: second?.deferStream,
92
+ ssrSource: second?.ssrSource
36
93
  } : undefined;
37
- const memo = createMemo(prev => first(prev), second, opts);
94
+ const memo = createMemo(prev => first(prev), opts);
38
95
  return [memo, () => undefined];
39
96
  }
40
97
  return [() => first, v => {
41
98
  return first = typeof v === "function" ? v(first) : v;
42
99
  }];
43
100
  }
44
- function createMemo(compute, value, options) {
101
+ function createMemo(compute, options) {
45
102
  const ctx = sharedConfig.context;
46
103
  const owner = signals.createOwner();
47
104
  const comp = {
48
105
  owner,
49
- value: value,
106
+ value: undefined,
50
107
  compute: compute,
51
108
  error: undefined,
52
109
  computed: false,
@@ -57,14 +114,15 @@ function createMemo(compute, value, options) {
57
114
  }));
58
115
  function update() {
59
116
  if (comp.disposed) return;
117
+ const run = () => signals.runWithOwner(owner, () => runWithObserver(comp, () => comp.compute(comp.value)));
60
118
  try {
61
119
  comp.error = undefined;
62
- const result = signals.runWithOwner(owner, () => runWithObserver(comp, () => comp.compute(comp.value)));
120
+ const result = run();
63
121
  comp.computed = true;
64
- processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource);
122
+ processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource, run);
65
123
  } catch (err) {
66
124
  if (err instanceof signals.NotReadyError) {
67
- err.source?.then(() => update(), () => update());
125
+ subscribePendingRetry(err, update);
68
126
  }
69
127
  comp.error = err;
70
128
  comp.computed = true;
@@ -146,7 +204,7 @@ function createDeepProxy(target, patches, basePath = []) {
146
204
  };
147
205
  return new Proxy(target, handler);
148
206
  }
149
- function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
207
+ function processResult(comp, result, owner, ctx, deferStream, ssrSource, rerun) {
150
208
  if (comp.disposed) return;
151
209
  const id = owner.id;
152
210
  const noHydrate = signals.getContext(NoHydrateContext, owner);
@@ -160,47 +218,78 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
160
218
  comp.error = result.v;
161
219
  return;
162
220
  }
163
- result.then(v => {
221
+ const deferred = createDeferredPromise();
222
+ if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream);
223
+ settleServerAsync(result, () => rerun ? rerun() : result, deferred, value => {
164
224
  result.s = 1;
165
- result.v = v;
166
- if (comp.disposed) return;
167
- comp.value = v;
225
+ result.v = value;
226
+ comp.value = value;
168
227
  comp.error = undefined;
169
- }, err => {
228
+ return value;
229
+ }, error => {
170
230
  result.s = 2;
171
- result.v = err;
172
- if (comp.disposed) return;
173
- comp.error = err;
174
- });
175
- if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, result, deferStream);
176
- comp.error = new signals.NotReadyError(result);
231
+ result.v = error;
232
+ comp.error = error;
233
+ }, () => comp.disposed);
234
+ comp.error = new signals.NotReadyError(deferred.promise);
177
235
  return;
178
236
  }
179
237
  const iterator = result?.[Symbol.asyncIterator];
180
238
  if (typeof iterator === "function") {
181
- const iter = iterator.call(result);
182
239
  if (ssrSource === "hybrid") {
183
- const promise = iter.next().then(v => {
184
- promise.s = 1;
185
- promise.v = v.value;
186
- if (!v.done) closeAsyncIterator(iter);
187
- if (comp.disposed) return v.value;
188
- comp.value = v.value;
240
+ let currentResult = result;
241
+ let iter;
242
+ const deferred = createDeferredPromise();
243
+ const runFirst = () => {
244
+ const source = currentResult ?? (rerun ? rerun() : result);
245
+ currentResult = undefined;
246
+ const nextIterator = source?.[Symbol.asyncIterator];
247
+ if (typeof nextIterator !== "function") {
248
+ throw new Error("Expected async iterator while retrying server createMemo");
249
+ }
250
+ iter = nextIterator.call(source);
251
+ return iter.next().then(value => {
252
+ if (!value.done) closeAsyncIterator(iter);
253
+ return value.value;
254
+ });
255
+ };
256
+ settleServerAsync(runFirst(), runFirst, deferred, value => {
257
+ comp.value = value;
189
258
  comp.error = undefined;
190
- return v.value;
191
- }, () => {});
192
- if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, promise, deferStream);
193
- comp.error = new signals.NotReadyError(promise);
259
+ return value;
260
+ }, error => {
261
+ comp.error = error;
262
+ }, () => comp.disposed);
263
+ if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream);
264
+ comp.error = new signals.NotReadyError(deferred.promise);
194
265
  } else {
195
- const firstNext = iter.next();
196
- const firstReady = firstNext.then(r => {
197
- if (comp.disposed) return;
198
- if (!r.done) {
199
- comp.value = r.value;
266
+ let currentResult = result;
267
+ let iter;
268
+ let firstResult;
269
+ const deferred = createDeferredPromise();
270
+ const runFirst = () => {
271
+ const source = currentResult ?? (rerun ? rerun() : result);
272
+ currentResult = undefined;
273
+ const nextIterator = source?.[Symbol.asyncIterator];
274
+ if (typeof nextIterator !== "function") {
275
+ throw new Error("Expected async iterator while retrying server createMemo");
276
+ }
277
+ iter = nextIterator.call(source);
278
+ return iter.next().then(value => {
279
+ firstResult = value;
280
+ return Promise.resolve();
281
+ });
282
+ };
283
+ settleServerAsync(runFirst(), runFirst, deferred, () => {
284
+ const resolved = firstResult;
285
+ if (resolved && !resolved.done) {
286
+ comp.value = resolved.value;
200
287
  }
201
288
  comp.error = undefined;
202
- return Promise.resolve();
203
- }, () => {});
289
+ return undefined;
290
+ }, error => {
291
+ comp.error = error;
292
+ }, () => comp.disposed);
204
293
  if (ctx?.async && ctx.serialize && id && !noHydrate) {
205
294
  let tappedFirst = true;
206
295
  const tapped = {
@@ -208,7 +297,10 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
208
297
  next() {
209
298
  if (tappedFirst) {
210
299
  tappedFirst = false;
211
- return firstNext.then(r => r);
300
+ return deferred.promise.then(() => firstResult?.done ? {
301
+ done: true,
302
+ value: undefined
303
+ } : firstResult);
212
304
  }
213
305
  return iter.next().then(r => r);
214
306
  },
@@ -219,7 +311,7 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
219
311
  };
220
312
  ctx.serialize(id, tapped, deferStream);
221
313
  }
222
- comp.error = new signals.NotReadyError(firstReady);
314
+ comp.error = new signals.NotReadyError(deferred.promise);
223
315
  }
224
316
  return;
225
317
  }
@@ -231,7 +323,7 @@ function closeAsyncIterator(iter, value) {
231
323
  returned.then(undefined, () => {});
232
324
  }
233
325
  }
234
- function serverEffect(compute, effectFn, value, options) {
326
+ function serverEffect(compute, effectFn, options) {
235
327
  const ssrSource = options?.ssrSource;
236
328
  if (ssrSource === "client" || ssrSource === "initial") {
237
329
  signals.createOwner();
@@ -241,7 +333,7 @@ function serverEffect(compute, effectFn, value, options) {
241
333
  const owner = signals.createOwner();
242
334
  const comp = {
243
335
  owner,
244
- value: value,
336
+ value: undefined,
245
337
  compute: compute,
246
338
  error: undefined,
247
339
  computed: true,
@@ -253,19 +345,19 @@ function serverEffect(compute, effectFn, value, options) {
253
345
  }));
254
346
  }
255
347
  try {
256
- const result = signals.runWithOwner(owner, () => runWithObserver(comp, () => compute(value)));
348
+ const result = signals.runWithOwner(owner, () => runWithObserver(comp, () => compute(undefined)));
257
349
  if (ssrSource) {
258
350
  processResult(comp, result, owner, ctx, options?.deferStream, ssrSource);
259
351
  }
260
- effectFn?.(ssrSource ? comp.value ?? result : result, value);
352
+ effectFn?.(ssrSource ? comp.value ?? result : result, undefined);
261
353
  } catch (err) {
262
354
  }
263
355
  }
264
- function createEffect(compute, effect, value, options) {
265
- serverEffect(compute, undefined, value, options);
356
+ function createEffect(compute, effect, options) {
357
+ serverEffect(compute, undefined, options);
266
358
  }
267
- function createRenderEffect(compute, effectFn, value, options) {
268
- serverEffect(compute, effectFn, value, options);
359
+ function createRenderEffect(compute, effectFn, options) {
360
+ serverEffect(compute, effectFn, options);
269
361
  }
270
362
  function createTrackedEffect(compute, options) {
271
363
  const o = signals.getOwner();
@@ -276,8 +368,8 @@ function createReaction(effectFn, options) {
276
368
  tracking();
277
369
  };
278
370
  }
279
- function createOptimistic(first, second, third) {
280
- return createSignal(first, second, third);
371
+ function createOptimistic(first, second) {
372
+ return createSignal(first, second);
281
373
  }
282
374
  function setProperty(state, property, value) {
283
375
  if (state[property] === value) return;
@@ -287,7 +379,7 @@ function setProperty(state, property, value) {
287
379
  }
288
380
  function createStore(first, second) {
289
381
  if (typeof first === "function") {
290
- const store = createProjection(first, second ?? {});
382
+ const store = createProjection(first, second);
291
383
  return [store, fn => fn(store)];
292
384
  }
293
385
  const state = first;
@@ -310,7 +402,7 @@ function createPendingProxy(state, source) {
310
402
  pending = false;
311
403
  }];
312
404
  }
313
- function createProjection(fn, initialValue = {}, options) {
405
+ function createProjection(fn, initialValue, options) {
314
406
  const ctx = sharedConfig.context;
315
407
  const owner = signals.createOwner();
316
408
  const [state] = createStore(initialValue);
@@ -325,43 +417,69 @@ function createProjection(fn, initialValue = {}, options) {
325
417
  const useProxy = ssrSource !== "hybrid";
326
418
  const patches = [];
327
419
  const draft = useProxy ? createDeepProxy(state, patches) : state;
328
- const result = signals.runWithOwner(owner, () => fn(draft));
420
+ const runProjection = () => signals.runWithOwner(owner, () => fn(draft));
421
+ const result = runProjection();
329
422
  const iteratorFn = result?.[Symbol.asyncIterator];
330
423
  if (typeof iteratorFn === "function") {
331
- const iter = iteratorFn.call(result);
332
424
  if (ssrSource === "hybrid") {
333
- const promise = iter.next().then(r => {
334
- promise.s = 1;
335
- if (!r.done) closeAsyncIterator(iter);
336
- if (disposed) {
337
- promise.v = state;
338
- return state;
425
+ let currentResult = result;
426
+ let iter;
427
+ const deferred = createDeferredPromise();
428
+ const [pending, markReady] = createPendingProxy(state, deferred.promise);
429
+ const runFirst = () => {
430
+ const source = currentResult ?? runProjection();
431
+ currentResult = undefined;
432
+ const nextIterator = source?.[Symbol.asyncIterator];
433
+ if (typeof nextIterator !== "function") {
434
+ throw new Error("Expected async iterator while retrying server createProjection");
339
435
  }
340
- if (r.value !== undefined && r.value !== state) {
341
- Object.assign(state, r.value);
436
+ iter = nextIterator.call(source);
437
+ return iter.next().then(r => {
438
+ if (!r.done) closeAsyncIterator(iter);
439
+ return r.value;
440
+ });
441
+ };
442
+ settleServerAsync(runFirst(), runFirst, deferred, value => {
443
+ if (value !== undefined && value !== state) {
444
+ Object.assign(state, value);
342
445
  }
343
- promise.v = state;
344
446
  markReady();
345
447
  return state;
346
- }, () => {});
347
- if (ctx?.async && !signals.getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, promise, options?.deferStream);
348
- const [pending, markReady] = createPendingProxy(state, promise);
448
+ }, error => {
449
+ markReady();
450
+ }, () => disposed);
451
+ if (ctx?.async && !signals.getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream);
349
452
  return pending;
350
453
  } else {
351
- const firstNext = iter.next();
352
- const firstReady = firstNext.then(r => {
353
- if (disposed) return;
454
+ let currentResult = result;
455
+ let iter;
456
+ let firstResult;
457
+ const deferred = createDeferredPromise();
458
+ const [pending, markReady] = createPendingProxy(state, deferred.promise);
459
+ const runFirst = () => {
460
+ const source = currentResult ?? runProjection();
461
+ currentResult = undefined;
462
+ const nextIterator = source?.[Symbol.asyncIterator];
463
+ if (typeof nextIterator !== "function") {
464
+ throw new Error("Expected async iterator while retrying server createProjection");
465
+ }
466
+ iter = nextIterator.call(source);
467
+ return iter.next().then(value => {
468
+ firstResult = value;
469
+ return Promise.resolve();
470
+ });
471
+ };
472
+ settleServerAsync(runFirst(), runFirst, deferred, () => {
354
473
  patches.length = 0;
355
- if (!r.done) {
356
- if (r.value !== undefined && r.value !== draft) {
357
- Object.assign(state, r.value);
358
- }
474
+ const resolved = firstResult;
475
+ if (resolved && !resolved.done && resolved.value !== undefined && resolved.value !== draft) {
476
+ Object.assign(state, resolved.value);
359
477
  }
360
478
  markReady(JSON.parse(JSON.stringify(state)));
361
- return Promise.resolve();
362
- }, () => {
479
+ return undefined;
480
+ }, error => {
363
481
  markReady();
364
- });
482
+ }, () => disposed);
365
483
  if (ctx?.async && !signals.getContext(NoHydrateContext) && owner.id) {
366
484
  let tappedFirst = true;
367
485
  const tapped = {
@@ -369,8 +487,8 @@ function createProjection(fn, initialValue = {}, options) {
369
487
  next() {
370
488
  if (tappedFirst) {
371
489
  tappedFirst = false;
372
- return firstNext.then(r => {
373
- if (r.done) return {
490
+ return deferred.promise.then(() => {
491
+ if (firstResult?.done) return {
374
492
  done: true,
375
493
  value: undefined
376
494
  };
@@ -408,25 +526,22 @@ function createProjection(fn, initialValue = {}, options) {
408
526
  };
409
527
  ctx.serialize(owner.id, tapped, options?.deferStream);
410
528
  }
411
- const [pending, markReady] = createPendingProxy(state, firstReady);
412
529
  return pending;
413
530
  }
414
531
  }
415
532
  if (result instanceof Promise) {
416
- const promise = result.then(v => {
417
- promise.s = 1;
418
- if (disposed) {
419
- promise.v = state;
420
- return;
533
+ const deferred = createDeferredPromise();
534
+ const [pending, markReady] = createPendingProxy(state, deferred.promise);
535
+ settleServerAsync(result, () => runProjection(), deferred, value => {
536
+ if (value !== undefined && value !== state) {
537
+ Object.assign(state, value);
421
538
  }
422
- if (v !== undefined && v !== state) {
423
- Object.assign(state, v);
424
- }
425
- promise.v = state;
426
539
  markReady();
427
- }, () => {});
428
- if (ctx?.async && !signals.getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, promise, options?.deferStream);
429
- const [pending, markReady] = createPendingProxy(state, promise);
540
+ return state;
541
+ }, error => {
542
+ markReady();
543
+ }, () => disposed);
544
+ if (ctx?.async && !signals.getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream);
430
545
  return pending;
431
546
  }
432
547
  if (result !== undefined && result !== state && result !== draft) {
@@ -568,6 +683,10 @@ function createLoadingBoundary$1(fn, fallback, options) {
568
683
  throw err;
569
684
  }
570
685
  }
686
+ function createRevealOrder(fn, _options) {
687
+ const o = signals.createOwner();
688
+ return signals.runWithOwner(o, fn);
689
+ }
571
690
  function untrack(fn) {
572
691
  return fn();
573
692
  }
@@ -620,10 +739,10 @@ function useContext(context) {
620
739
  return signals.getContext(context);
621
740
  }
622
741
  function children(fn) {
623
- const c = createMemo(fn, undefined, {
742
+ const c = createMemo(fn, {
624
743
  lazy: true
625
744
  });
626
- const memo = createMemo(() => signals.flatten(c()), undefined, {
745
+ const memo = createMemo(() => signals.flatten(c()), {
627
746
  lazy: true
628
747
  });
629
748
  memo.toArray = () => {
@@ -692,6 +811,10 @@ function createUniqueId() {
692
811
  return signals.getNextChildId(o);
693
812
  }
694
813
 
814
+ const RevealGroupContext = {
815
+ id: Symbol("RevealGroupContext"),
816
+ defaultValue: null
817
+ };
695
818
  function ssrHandleError(err) {
696
819
  if (err instanceof signals.NotReadyError) {
697
820
  return err.source;
@@ -717,6 +840,7 @@ function createLoadingBoundary(fn, fallback, options) {
717
840
  const ctx = currentCtx;
718
841
  const parent = signals.getOwner();
719
842
  const parentHandler = parent && signals.runWithOwner(parent, () => signals.getContext(ErrorContext));
843
+ const revealGroup = parent && signals.runWithOwner(parent, () => signals.getContext(RevealGroupContext));
720
844
  const o = signals.createOwner();
721
845
  const id = o.id;
722
846
  o.id = id + "00";
@@ -779,12 +903,25 @@ function createLoadingBoundary(fn, fallback, options) {
779
903
  commitBoundaryState();
780
904
  return () => ret;
781
905
  }
906
+ const collapseFallback = revealGroup ? revealGroup.register(id) : false;
907
+ if (collapseFallback && !ctx.async) {
908
+ commitBoundaryState();
909
+ ctx.serialize(id, "$$f");
910
+ return () => undefined;
911
+ }
782
912
  const fallbackOwner = signals.createOwner({
783
913
  id
784
914
  });
785
- const fallbackResult = signals.runWithOwner(fallbackOwner, () => ctx.async ? ctx.ssr([`<template id="pl-${id}"></template>`, `<!--pl-${id}-->`], ctx.escape(fallback())) : fallback());
915
+ const fallbackResult = signals.runWithOwner(fallbackOwner, () => {
916
+ if (!ctx.async) return fallback();
917
+ const tpl = collapseFallback ? [`<template id="pl-${id}">`, `</template><!--pl-${id}-->`] : [`<template id="pl-${id}"></template>`, `<!--pl-${id}-->`];
918
+ return ctx.ssr(tpl, ctx.escape(fallback()));
919
+ });
786
920
  if (ctx.async) {
787
- done = ctx.registerFragment(id);
921
+ const regOpts = revealGroup ? {
922
+ revealGroup: revealGroup.id
923
+ } : undefined;
924
+ done = ctx.registerFragment(id, regOpts);
788
925
  (async () => {
789
926
  try {
790
927
  commitBoundaryState();
@@ -794,6 +931,7 @@ function createLoadingBoundary(fn, fallback, options) {
794
931
  }
795
932
  flushSerializeBuffer();
796
933
  done(ret.t[0]);
934
+ if (revealGroup) revealGroup.onResolved(id);
797
935
  } catch (err) {
798
936
  finalizeError(err);
799
937
  }
@@ -885,6 +1023,97 @@ function Errored(props) {
885
1023
  function Loading(props) {
886
1024
  return createLoadingBoundary(() => props.children, () => props.fallback);
887
1025
  }
1026
+ function Reveal(props) {
1027
+ const o = signals.createOwner();
1028
+ const id = o.id;
1029
+ const together = !!props.together;
1030
+ const collapsed = !!props.collapsed;
1031
+ if (!sharedConfig.context?.async) {
1032
+ const parent = signals.getOwner();
1033
+ const parentGroup = parent ? signals.runWithOwner(parent, () => signals.getContext(RevealGroupContext)) : null;
1034
+ let collapsedByParent = false;
1035
+ if (parentGroup) {
1036
+ collapsedByParent = parentGroup.register(id);
1037
+ if (collapsed || together) console.warn("Nested <Reveal> with collapsed/together won't coordinate correctly with renderToString. Use renderToStream for full support.");
1038
+ }
1039
+ let count = 0;
1040
+ return signals.runWithOwner(o, () => {
1041
+ signals.setContext(RevealGroupContext, {
1042
+ id,
1043
+ register(_key) {
1044
+ count++;
1045
+ if (collapsedByParent) return true;
1046
+ return !together && collapsed && count > 1;
1047
+ },
1048
+ onResolved() {}
1049
+ });
1050
+ return props.children;
1051
+ });
1052
+ }
1053
+ const ctx = sharedConfig.context;
1054
+ const keys = [];
1055
+ const resolved = new Set();
1056
+ const composites = new Map();
1057
+ let frontier = 0;
1058
+ const parent = signals.getOwner();
1059
+ const parentGroup = parent ? signals.runWithOwner(parent, () => signals.getContext(RevealGroupContext)) : null;
1060
+ let collapsedByParent = false;
1061
+ if (parentGroup) {
1062
+ collapsedByParent = parentGroup.register(id, {
1063
+ onActivate: () => {
1064
+ collapsedByParent = false;
1065
+ advanceFrontier();
1066
+ }
1067
+ });
1068
+ }
1069
+ function notifyParentIfDone() {
1070
+ if (parentGroup && resolved.size === keys.length) {
1071
+ parentGroup.onResolved(id);
1072
+ }
1073
+ }
1074
+ function advanceFrontier() {
1075
+ while (frontier < keys.length && resolved.has(keys[frontier])) {
1076
+ if (!composites.has(keys[frontier])) ctx.revealFragments?.([keys[frontier]]);
1077
+ frontier++;
1078
+ }
1079
+ if (frontier < keys.length) {
1080
+ const activate = composites.get(keys[frontier]);
1081
+ if (activate) activate();else if (!together && collapsed) ctx.revealFallbacks?.(keys.slice(frontier));
1082
+ }
1083
+ notifyParentIfDone();
1084
+ }
1085
+ return signals.runWithOwner(o, () => {
1086
+ signals.setContext(RevealGroupContext, {
1087
+ id,
1088
+ register(key, options) {
1089
+ keys.push(key);
1090
+ if (options?.onActivate) composites.set(key, options.onActivate);
1091
+ if (collapsedByParent) return true;
1092
+ return !together && collapsed && keys.length > 1;
1093
+ },
1094
+ onResolved(key) {
1095
+ resolved.add(key);
1096
+ if (collapsedByParent) {
1097
+ notifyParentIfDone();
1098
+ return;
1099
+ }
1100
+ if (together) {
1101
+ if (resolved.size === keys.length) {
1102
+ ctx.revealFragments?.(id);
1103
+ notifyParentIfDone();
1104
+ }
1105
+ } else {
1106
+ advanceFrontier();
1107
+ }
1108
+ }
1109
+ });
1110
+ const result = props.children;
1111
+ if (parentGroup && keys.length === 0) {
1112
+ parentGroup.onResolved(id);
1113
+ }
1114
+ return result;
1115
+ });
1116
+ }
888
1117
 
889
1118
  const DEV = undefined;
890
1119
 
@@ -932,6 +1161,10 @@ Object.defineProperty(exports, "getOwner", {
932
1161
  enumerable: true,
933
1162
  get: function () { return signals.getOwner; }
934
1163
  });
1164
+ Object.defineProperty(exports, "isDisposed", {
1165
+ enumerable: true,
1166
+ get: function () { return signals.isDisposed; }
1167
+ });
935
1168
  Object.defineProperty(exports, "isEqual", {
936
1169
  enumerable: true,
937
1170
  get: function () { return signals.isEqual; }
@@ -974,6 +1207,7 @@ exports.Match = Match;
974
1207
  exports.NoHydrateContext = NoHydrateContext;
975
1208
  exports.NoHydration = NoHydration;
976
1209
  exports.Repeat = Repeat;
1210
+ exports.Reveal = Reveal;
977
1211
  exports.Show = Show;
978
1212
  exports.Switch = Switch;
979
1213
  exports.action = action;
@@ -990,6 +1224,7 @@ exports.createOptimisticStore = createOptimisticStore;
990
1224
  exports.createProjection = createProjection;
991
1225
  exports.createReaction = createReaction;
992
1226
  exports.createRenderEffect = createRenderEffect;
1227
+ exports.createRevealOrder = createRevealOrder;
993
1228
  exports.createSignal = createSignal;
994
1229
  exports.createStore = createStore;
995
1230
  exports.createTrackedEffect = createTrackedEffect;