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

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
@@ -1,4 +1,4 @@
1
- import { getOwner, getContext, getNextChildId, createOwner, runWithOwner, setContext, NotReadyError, onCleanup, isWrappable, flatten, createRoot } from '@solidjs/signals';
1
+ import { getOwner, getContext, getNextChildId, createOwner, NotReadyError, runWithOwner, onCleanup, isWrappable, setContext, flatten, createRoot } from '@solidjs/signals';
2
2
  export { $PROXY, $REFRESH, $TRACK, NotReadyError, createOwner, createRoot, enableExternalSource, enforceLoadingBoundary, flatten, getNextChildId, getOwner, isEqual, isWrappable, merge, omit, onCleanup, runWithOwner, snapshot, storePath } from '@solidjs/signals';
3
3
 
4
4
  const NoHydrateContext = {
@@ -63,7 +63,7 @@ function createMemo(compute, value, options) {
63
63
  processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource);
64
64
  } catch (err) {
65
65
  if (err instanceof NotReadyError) {
66
- err.source?.then(() => update());
66
+ err.source?.then(() => update(), () => update());
67
67
  }
68
68
  comp.error = err;
69
69
  comp.computed = true;
@@ -148,20 +148,31 @@ function createDeepProxy(target, patches, basePath = []) {
148
148
  function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
149
149
  if (comp.disposed) return;
150
150
  const id = owner.id;
151
- const uninitialized = comp.value === undefined;
152
151
  const noHydrate = getContext(NoHydrateContext, owner);
153
152
  if (result instanceof Promise) {
153
+ if (result.s === 1) {
154
+ comp.value = result.v;
155
+ comp.error = undefined;
156
+ return;
157
+ }
158
+ if (result.s === 2) {
159
+ comp.error = result.v;
160
+ return;
161
+ }
154
162
  result.then(v => {
155
163
  result.s = 1;
156
164
  result.v = v;
157
165
  if (comp.disposed) return;
158
166
  comp.value = v;
159
167
  comp.error = undefined;
160
- }, () => {});
168
+ }, err => {
169
+ result.s = 2;
170
+ result.v = err;
171
+ if (comp.disposed) return;
172
+ comp.error = err;
173
+ });
161
174
  if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, result, deferStream);
162
- if (uninitialized) {
163
- comp.error = new NotReadyError(result);
164
- }
175
+ comp.error = new NotReadyError(result);
165
176
  return;
166
177
  }
167
178
  const iterator = result?.[Symbol.asyncIterator];
@@ -171,6 +182,7 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
171
182
  const promise = iter.next().then(v => {
172
183
  promise.s = 1;
173
184
  promise.v = v.value;
185
+ if (!v.done) closeAsyncIterator(iter);
174
186
  if (comp.disposed) return v.value;
175
187
  comp.value = v.value;
176
188
  comp.error = undefined;
@@ -198,6 +210,9 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
198
210
  return firstNext.then(r => r);
199
211
  }
200
212
  return iter.next().then(r => r);
213
+ },
214
+ return(value) {
215
+ return iter.return?.(value);
201
216
  }
202
217
  })
203
218
  };
@@ -209,6 +224,12 @@ function processResult(comp, result, owner, ctx, deferStream, ssrSource) {
209
224
  }
210
225
  comp.value = result;
211
226
  }
227
+ function closeAsyncIterator(iter, value) {
228
+ const returned = iter.return?.(value);
229
+ if (returned && typeof returned.then === "function") {
230
+ returned.then(undefined, () => {});
231
+ }
232
+ }
212
233
  function serverEffect(compute, effectFn, value, options) {
213
234
  const ssrSource = options?.ssrSource;
214
235
  if (ssrSource === "client" || ssrSource === "initial") {
@@ -310,6 +331,7 @@ function createProjection(fn, initialValue = {}, options) {
310
331
  if (ssrSource === "hybrid") {
311
332
  const promise = iter.next().then(r => {
312
333
  promise.s = 1;
334
+ if (!r.done) closeAsyncIterator(iter);
313
335
  if (disposed) {
314
336
  promise.v = state;
315
337
  return state;
@@ -377,6 +399,9 @@ function createProjection(fn, initialValue = {}, options) {
377
399
  value: undefined
378
400
  };
379
401
  });
402
+ },
403
+ return(value) {
404
+ return iter.return?.(value);
380
405
  }
381
406
  })
382
407
  };
@@ -428,7 +453,7 @@ function deep(store) {
428
453
  }
429
454
  function mapArray(list, mapFn, options = {}) {
430
455
  const parent = createOwner();
431
- return () => {
456
+ return createMemo(() => {
432
457
  const items = list();
433
458
  let s = [];
434
459
  if (items && items.length) {
@@ -445,54 +470,93 @@ function mapArray(list, mapFn, options = {}) {
445
470
  })];
446
471
  }
447
472
  return s;
448
- };
473
+ });
449
474
  }
450
475
  function repeat(count, mapFn, options = {}) {
451
476
  const owner = createOwner();
452
- const len = count();
453
- const offset = options.from?.() || 0;
454
- let s = [];
455
- if (len) {
456
- runWithOwner(owner, () => {
457
- for (let i = 0; i < len; i++) {
458
- const itemOwner = createOwner();
459
- s.push(runWithOwner(itemOwner, () => mapFn(i + offset)));
460
- }
461
- });
462
- } else if (options.fallback) {
463
- s = [runWithOwner(owner, () => {
464
- const fo = createOwner();
465
- return runWithOwner(fo, () => options.fallback());
466
- })];
467
- }
468
- return () => s;
477
+ return createMemo(() => {
478
+ const len = count();
479
+ const offset = options.from?.() || 0;
480
+ if (!len) {
481
+ if (!options.fallback) return [];
482
+ return [runWithOwner(owner, () => {
483
+ const fallbackOwner = createOwner();
484
+ return runWithOwner(fallbackOwner, () => options.fallback());
485
+ })];
486
+ }
487
+ return runWithOwner(owner, () => Array.from({
488
+ length: len
489
+ }, (_, i) => {
490
+ const itemOwner = createOwner();
491
+ return runWithOwner(itemOwner, () => mapFn(i + offset));
492
+ }));
493
+ });
469
494
  }
470
495
  const ErrorContext = {
471
496
  id: Symbol("ErrorContext"),
472
497
  defaultValue: null
473
498
  };
499
+ function runWithBoundaryErrorContext(owner, render, onError, context, boundaryId) {
500
+ const prevCtx = sharedConfig.context;
501
+ const prevBoundary = context?._currentBoundaryId;
502
+ if (context) {
503
+ sharedConfig.context = context;
504
+ if (boundaryId !== undefined) context._currentBoundaryId = boundaryId;
505
+ }
506
+ try {
507
+ return runWithOwner(owner, () => {
508
+ const parentHandler = getContext(ErrorContext);
509
+ setContext(ErrorContext, err => onError(err, parentHandler));
510
+ return render();
511
+ });
512
+ } finally {
513
+ if (context) {
514
+ if (boundaryId !== undefined) context._currentBoundaryId = prevBoundary;
515
+ sharedConfig.context = prevCtx;
516
+ }
517
+ }
518
+ }
474
519
  function createErrorBoundary(fn, fallback) {
475
520
  const ctx = sharedConfig.context;
476
- const owner = createOwner();
477
521
  const parent = getOwner();
478
- if (parent?.id != null) getNextChildId(parent);
479
- owner.id = owner.id + "0";
480
- return runWithOwner(owner, () => {
522
+ const owner = createOwner();
523
+ const resolve = () => {
524
+ const resolved = ctx.resolve(runWithOwner(createOwner(), fn));
525
+ if (resolved?.p?.length) throw new NotReadyError(Promise.all(resolved.p));
526
+ return resolved;
527
+ };
528
+ const renderFallback = err => ctx ? runWithOwner(parent, () => {
529
+ const fallbackOwner = createOwner();
530
+ return runWithOwner(fallbackOwner, () => fallback(err, () => {}));
531
+ }) : fallback(err, () => {});
532
+ const serializeError = err => {
533
+ if (ctx && owner.id && !runWithOwner(owner, () => getContext(NoHydrateContext))) {
534
+ ctx.serialize(owner.id, err);
535
+ }
536
+ };
537
+ const handleError = err => {
538
+ serializeError(err);
539
+ return renderFallback(err);
540
+ };
541
+ return () => {
481
542
  let result;
482
- setContext(ErrorContext, err => {
483
- if (ctx && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, err);
484
- result = fallback(err, () => {});
485
- });
543
+ let handled = false;
544
+ if (ctx) owner.dispose(false);
486
545
  try {
487
- result = fn();
546
+ result = ctx ? runWithBoundaryErrorContext(owner, resolve, err => {
547
+ if (err instanceof NotReadyError) throw err;
548
+ handled = true;
549
+ result = handleError(err);
550
+ throw err;
551
+ }) : runWithOwner(owner, fn);
488
552
  } catch (err) {
489
- if (ctx && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, err);
490
- result = fallback(err, () => {});
553
+ if (err instanceof NotReadyError) throw err;
554
+ result = handled ? result : handleError(err);
491
555
  }
492
- return () => result;
493
- });
556
+ return result;
557
+ };
494
558
  }
495
- function createLoadingBoundary(fn, fallback, options) {
559
+ function createLoadingBoundary$1(fn, fallback, options) {
496
560
  try {
497
561
  const result = fn();
498
562
  return () => result;
@@ -568,7 +632,9 @@ function children(fn) {
568
632
  return memo;
569
633
  }
570
634
  function ssrRunInScope(fn) {
571
- return fn;
635
+ const owner = getOwner();
636
+ if (!owner) return fn;
637
+ return Array.isArray(fn) ? fn.map(hole => () => runWithOwner(owner, hole)) : () => runWithOwner(owner, fn);
572
638
  }
573
639
 
574
640
  function enableHydration() {}
@@ -625,6 +691,136 @@ function createUniqueId() {
625
691
  return getNextChildId(o);
626
692
  }
627
693
 
694
+ function ssrHandleError(err) {
695
+ if (err instanceof NotReadyError) {
696
+ return err.source;
697
+ }
698
+ const handler = getContext(ErrorContext);
699
+ if (handler) {
700
+ handler(err);
701
+ return;
702
+ }
703
+ throw err;
704
+ }
705
+ class InvalidTopLevelAsyncReadError extends Error {
706
+ constructor() {
707
+ super("Async values must be read within a tracking scope (JSX, a memo, or an effect's compute function).");
708
+ this.name = "InvalidTopLevelAsyncReadError";
709
+ }
710
+ }
711
+ function createLoadingBoundary(fn, fallback, options) {
712
+ const currentCtx = sharedConfig.context;
713
+ if (!currentCtx) {
714
+ return createLoadingBoundary$1(fn, fallback);
715
+ }
716
+ const ctx = currentCtx;
717
+ const parent = getOwner();
718
+ const parentHandler = parent && runWithOwner(parent, () => getContext(ErrorContext));
719
+ const o = createOwner();
720
+ const id = o.id;
721
+ o.id = id + "00";
722
+ let done;
723
+ let handledRenderError;
724
+ let serializeBuffer = [];
725
+ const bufferedCtx = Object.create(ctx);
726
+ bufferedCtx.serialize = (id, value, deferStream) => {
727
+ serializeBuffer.push([id, value, deferStream]);
728
+ };
729
+ bufferedCtx._currentBoundaryId = id;
730
+ function flushSerializeBuffer() {
731
+ for (const args of serializeBuffer) ctx.serialize(args[0], args[1], args[2]);
732
+ serializeBuffer = [];
733
+ }
734
+ function commitBoundaryState() {
735
+ flushSerializeBuffer();
736
+ const modules = ctx.getBoundaryModules?.(id);
737
+ if (modules) ctx.serialize(id + "_assets", modules);
738
+ }
739
+ function runLoadingPhase(render) {
740
+ handledRenderError = undefined;
741
+ return runWithBoundaryErrorContext(o, render, (err, parentHandler) => {
742
+ handledRenderError = err;
743
+ if (done?.(undefined, err)) throw err;
744
+ if (parentHandler) {
745
+ parentHandler(err);
746
+ return;
747
+ }
748
+ throw err;
749
+ }, bufferedCtx, id);
750
+ }
751
+ function finalizeError(err) {
752
+ if (handledRenderError === err) {
753
+ handledRenderError = undefined;
754
+ return;
755
+ }
756
+ if (done?.(undefined, err)) return;
757
+ if (!parentHandler) throw err;
758
+ try {
759
+ runWithOwner(parent, () => parentHandler(err));
760
+ } catch (caught) {
761
+ if (caught !== err) throw caught;
762
+ }
763
+ }
764
+ function runDiscovery() {
765
+ o.dispose(false);
766
+ serializeBuffer = [];
767
+ return runLoadingPhase(() => {
768
+ try {
769
+ return ctx.resolve(fn());
770
+ } catch (err) {
771
+ if (err instanceof NotReadyError) throw new InvalidTopLevelAsyncReadError();
772
+ throw err;
773
+ }
774
+ });
775
+ }
776
+ let ret = runDiscovery();
777
+ if (!ret?.p?.length) {
778
+ commitBoundaryState();
779
+ return () => ret;
780
+ }
781
+ const fallbackOwner = createOwner({
782
+ id
783
+ });
784
+ const fallbackResult = runWithOwner(fallbackOwner, () => ctx.async ? ctx.ssr([`<template id="pl-${id}"></template>`, `<!--pl-${id}-->`], ctx.escape(fallback())) : fallback());
785
+ if (ctx.async) {
786
+ done = ctx.registerFragment(id);
787
+ (async () => {
788
+ try {
789
+ commitBoundaryState();
790
+ while (ret.p.length) {
791
+ await Promise.all(ret.p).catch(() => {});
792
+ ret = runLoadingPhase(() => ctx.ssr(ret.t, ...ret.h));
793
+ }
794
+ flushSerializeBuffer();
795
+ done(ret.t[0]);
796
+ } catch (err) {
797
+ finalizeError(err);
798
+ }
799
+ })();
800
+ return () => fallbackResult;
801
+ }
802
+ commitBoundaryState();
803
+ ctx.serialize(id, "$$f");
804
+ return () => fallbackResult;
805
+ }
806
+ function NoHydration(props) {
807
+ const o = createOwner();
808
+ return runWithOwner(o, () => {
809
+ setContext(NoHydrateContext, true);
810
+ return props.children;
811
+ });
812
+ }
813
+ function Hydration(props) {
814
+ if (!getContext(NoHydrateContext)) return props.children;
815
+ const o = createOwner({
816
+ id: props.id ?? ""
817
+ });
818
+ return runWithOwner(o, () => {
819
+ setContext(NoHydrateContext, false);
820
+ return props.children;
821
+ });
822
+ }
823
+
628
824
  function For(props) {
629
825
  const options = "fallback" in props ? {
630
826
  keyed: props.keyed,
@@ -632,7 +828,7 @@ function For(props) {
632
828
  } : {
633
829
  keyed: props.keyed
634
830
  };
635
- return createMemo(mapArray(() => props.each, props.children, options));
831
+ return mapArray(() => props.each, props.children, options);
636
832
  }
637
833
  function Repeat(props) {
638
834
  const options = "fallback" in props ? {
@@ -685,106 +881,8 @@ function Errored(props) {
685
881
  return typeof f === "function" && f.length ? f(err, reset) : f;
686
882
  });
687
883
  }
688
-
689
- function ssrHandleError(err) {
690
- if (err instanceof NotReadyError) {
691
- return err.source;
692
- }
693
- const handler = getContext(ErrorContext);
694
- if (handler) {
695
- handler(err);
696
- return;
697
- }
698
- throw err;
699
- }
700
884
  function Loading(props) {
701
- const ctx = sharedConfig.context;
702
- if (!ctx) {
703
- return createLoadingBoundary(() => props.children, () => props.fallback);
704
- }
705
- const o = createOwner();
706
- const id = o.id;
707
- o.id = id + "00";
708
- let runPromise;
709
- let serializeBuffer = [];
710
- const origSerialize = ctx.serialize;
711
- function runInitially() {
712
- o.dispose(false);
713
- serializeBuffer = [];
714
- ctx.serialize = (id, p, deferStream) => {
715
- serializeBuffer.push([id, p, deferStream]);
716
- };
717
- const prevBoundary = ctx._currentBoundaryId;
718
- ctx._currentBoundaryId = id;
719
- const result = runWithOwner(o, () => {
720
- try {
721
- return ctx.resolve(props.children);
722
- } catch (err) {
723
- runPromise = ssrHandleError(err);
724
- }
725
- });
726
- ctx._currentBoundaryId = prevBoundary;
727
- ctx.serialize = origSerialize;
728
- return result;
729
- }
730
- let ret = runInitially();
731
- if (!(runPromise || ret?.p?.length)) {
732
- for (const args of serializeBuffer) origSerialize(args[0], args[1], args[2]);
733
- serializeBuffer = [];
734
- const modules = ctx.getBoundaryModules?.(id);
735
- if (modules) ctx.serialize(id + "_assets", modules);
736
- return ret;
737
- }
738
- const fallbackOwner = createOwner({
739
- id
740
- });
741
- getNextChildId(fallbackOwner);
742
- if (ctx.async) {
743
- const done = ctx.registerFragment(id);
744
- (async () => {
745
- try {
746
- while (runPromise) {
747
- o.dispose(false);
748
- await runPromise;
749
- runPromise = undefined;
750
- ret = runInitially();
751
- }
752
- for (const args of serializeBuffer) origSerialize(args[0], args[1], args[2]);
753
- serializeBuffer = [];
754
- while (ret.p.length) {
755
- await Promise.all(ret.p);
756
- ret = runWithOwner(o, () => ctx.ssr(ret.t, ...ret.h));
757
- }
758
- done(ret.t[0]);
759
- } catch (err) {
760
- done(undefined, err);
761
- }
762
- })();
763
- return runWithOwner(fallbackOwner, () => ctx.ssr([`<template id="pl-${id}"></template>`, `<!--pl-${id}-->`], ctx.escape(props.fallback)));
764
- }
765
- for (const args of serializeBuffer) origSerialize(args[0], args[1], args[2]);
766
- serializeBuffer = [];
767
- const modules = ctx.getBoundaryModules?.(id);
768
- if (modules) ctx.serialize(id + "_assets", modules);
769
- ctx.serialize(id, "$$f");
770
- return runWithOwner(fallbackOwner, () => props.fallback);
771
- }
772
- function NoHydration(props) {
773
- const o = createOwner();
774
- return runWithOwner(o, () => {
775
- setContext(NoHydrateContext, true);
776
- return props.children;
777
- });
778
- }
779
- function Hydration(props) {
780
- if (!getContext(NoHydrateContext)) return props.children;
781
- const o = createOwner({
782
- id: props.id ?? ""
783
- });
784
- return runWithOwner(o, () => {
785
- setContext(NoHydrateContext, false);
786
- return props.children;
787
- });
885
+ return createLoadingBoundary(() => props.children, () => props.fallback);
788
886
  }
789
887
 
790
888
  const DEV = undefined;