@solidjs/signals 0.8.6 → 0.9.0

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.js CHANGED
@@ -328,6 +328,7 @@ let tracking = false;
328
328
  let stale = false;
329
329
  let pendingValueCheck = false;
330
330
  let pendingCheck = null;
331
+ let refreshing = false;
331
332
  let context = null;
332
333
  function notifySubs(node) {
333
334
  for (let s = node._subs; s !== null; s = s._nextSub) {
@@ -364,7 +365,7 @@ function recompute(el, create = false) {
364
365
  setStatusFlags(el, STATUS_NONE | (prevStatusFlags & STATUS_UNINITIALIZED));
365
366
  tracking = true;
366
367
  try {
367
- value = el._fn(value);
368
+ value = handleAsync(el, el._fn(value));
368
369
  el._statusFlags &= ~STATUS_UNINITIALIZED;
369
370
  } catch (e) {
370
371
  if (e instanceof NotReadyError) {
@@ -413,15 +414,59 @@ function recompute(el, create = false) {
413
414
  insertIntoHeapHeight(s._sub, s._sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
414
415
  }
415
416
  }
416
- if (
417
- (!create || el._statusFlags & STATUS_PENDING) &&
418
- !el._optimistic &&
419
- !honoraryOptimistic &&
420
- !el._transition
421
- )
417
+ if ((!create || el._statusFlags & STATUS_PENDING) && !el._optimistic && !el._transition)
422
418
  globalQueue._pendingNodes.push(el);
423
419
  if (el._transition && honoraryOptimistic) runInTransition(el, recompute);
424
420
  }
421
+ function handleAsync(el, result, setter) {
422
+ const isObject = typeof result === "object" && result !== null;
423
+ const isPromise = isObject && result instanceof Promise;
424
+ const iterator = isObject && untrack(() => result[Symbol.asyncIterator]);
425
+ if (!isPromise && !iterator) {
426
+ el._inFlight = null;
427
+ return result;
428
+ }
429
+ el._inFlight = result;
430
+ if (isPromise) {
431
+ result
432
+ .then(value => {
433
+ if (el._inFlight !== result) return;
434
+ globalQueue.initTransition(el);
435
+ setter?.(value) ?? setSignal(el, () => value);
436
+ flush();
437
+ })
438
+ .catch(e => {
439
+ if (el._inFlight !== result) return;
440
+ globalQueue.initTransition(el);
441
+ setStatusFlags(el, STATUS_ERROR, e);
442
+ el._time = clock;
443
+ notifySubs(el);
444
+ schedule();
445
+ flush();
446
+ });
447
+ } else {
448
+ (async () => {
449
+ try {
450
+ for await (let value of result) {
451
+ if (el._inFlight !== result) return;
452
+ globalQueue.initTransition(el);
453
+ setter?.(value) ?? setSignal(el, () => value);
454
+ flush();
455
+ }
456
+ } catch (error) {
457
+ if (el._inFlight !== result) return;
458
+ globalQueue.initTransition(el);
459
+ setStatusFlags(el, STATUS_ERROR, error);
460
+ el._time = clock;
461
+ notifySubs(el);
462
+ schedule();
463
+ flush();
464
+ }
465
+ })();
466
+ }
467
+ globalQueue.initTransition(el);
468
+ throw new NotReadyError(context);
469
+ }
425
470
  function updateIfNecessary(el) {
426
471
  if (el._flags & REACTIVE_CHECK) {
427
472
  for (let d = el._deps; d; d = d._nextDep) {
@@ -605,6 +650,7 @@ function computed(fn, initialValue, options) {
605
650
  _pendingValue: NOT_PENDING,
606
651
  _pendingDisposal: null,
607
652
  _pendingFirstChild: null,
653
+ _inFlight: null,
608
654
  _transition: null
609
655
  };
610
656
  if (options?._internal) Object.assign(self, options._internal);
@@ -624,67 +670,6 @@ function computed(fn, initialValue, options) {
624
670
  recompute(self, true);
625
671
  return self;
626
672
  }
627
- function asyncComputed(asyncFn, initialValue, options) {
628
- let lastResult = undefined;
629
- let refreshing = false;
630
- const fn = prev => {
631
- const result = asyncFn(prev, refreshing);
632
- refreshing = false;
633
- lastResult = result;
634
- const isPromise = result instanceof Promise;
635
- const iterator = result[Symbol.asyncIterator];
636
- if (!isPromise && !iterator) {
637
- return result;
638
- }
639
- if (isPromise) {
640
- result
641
- .then(v => {
642
- if (lastResult !== result) return;
643
- globalQueue.initTransition(self);
644
- setSignal(self, () => v);
645
- flush();
646
- })
647
- .catch(e => {
648
- if (lastResult !== result) return;
649
- globalQueue.initTransition(self);
650
- setStatusFlags(self, STATUS_ERROR, e);
651
- self._time = clock;
652
- notifySubs(self);
653
- schedule();
654
- flush();
655
- });
656
- } else {
657
- (async () => {
658
- try {
659
- for await (let value of result) {
660
- if (lastResult !== result) return;
661
- globalQueue.initTransition(self);
662
- setSignal(self, () => value);
663
- flush();
664
- }
665
- } catch (error) {
666
- if (lastResult !== result) return;
667
- globalQueue.initTransition(self);
668
- setStatusFlags(self, STATUS_ERROR, error);
669
- self._time = clock;
670
- notifySubs(self);
671
- schedule();
672
- flush();
673
- }
674
- })();
675
- }
676
- globalQueue.initTransition(context);
677
- throw new NotReadyError(context);
678
- };
679
- const self = computed(fn, initialValue, options);
680
- self._refresh = () => {
681
- refreshing = true;
682
- recompute(self);
683
- schedule();
684
- flush();
685
- };
686
- return self;
687
- }
688
673
  function signal(v, options, firewall = null) {
689
674
  const s = {
690
675
  id: options?.id ?? (context?.id != null ? getNextChildId(context) : undefined),
@@ -719,6 +704,7 @@ function untrack(fn) {
719
704
  function read(el) {
720
705
  let c = context;
721
706
  if (c?._root) c = c._parentComputed;
707
+ if (refreshing && el._fn) recompute(el);
722
708
  if (c && tracking && !pendingCheck && !pendingValueCheck) {
723
709
  if (el._fn && el._flags & REACTIVE_DISPOSED) recompute(el);
724
710
  link(el, c);
@@ -900,6 +886,22 @@ function isPending(fn) {
900
886
  pendingCheck = current;
901
887
  }
902
888
  }
889
+ function refresh(fn) {
890
+ let prevRefreshing = refreshing;
891
+ refreshing = true;
892
+ try {
893
+ return untrack(fn);
894
+ } finally {
895
+ refreshing = prevRefreshing;
896
+ if (!prevRefreshing) {
897
+ schedule();
898
+ flush();
899
+ }
900
+ }
901
+ }
902
+ function isRefreshing() {
903
+ return refreshing;
904
+ }
903
905
  function createContext(defaultValue, description) {
904
906
  return { id: Symbol(description), defaultValue: defaultValue };
905
907
  }
@@ -1009,12 +1011,6 @@ function createMemo(compute, value, options) {
1009
1011
  let node = computed(compute, value, options);
1010
1012
  return read.bind(null, node);
1011
1013
  }
1012
- function createAsync(compute, value, options) {
1013
- const node = asyncComputed(compute, value, options);
1014
- const ret = read.bind(null, node);
1015
- ret.refresh = node._refresh;
1016
- return ret;
1017
- }
1018
1014
  function createEffect(compute, effectFn, value, options) {
1019
1015
  void effect(compute, effectFn.effect || effectFn, effectFn.error, value, {
1020
1016
  ...options,
@@ -1237,11 +1233,14 @@ function createProjectionInternal(fn, initialValue = {}, options) {
1237
1233
  };
1238
1234
  const wrappedStore = wrapProjection(initialValue);
1239
1235
  node = computed(() => {
1236
+ const owner = node || getOwner();
1240
1237
  storeSetter(wrappedStore, s => {
1241
- const value = fn(s);
1242
- if (value !== s && value !== undefined) {
1243
- reconcile(value, options?.key || "id", options?.all)(s);
1244
- }
1238
+ const value = handleAsync(owner, fn(s), value => {
1239
+ value !== s &&
1240
+ value !== undefined &&
1241
+ storeSetter(wrappedStore, reconcile(value, options?.key || "id", options?.all));
1242
+ });
1243
+ value !== s && value !== undefined && reconcile(value, options?.key || "id", options?.all)(s);
1245
1244
  });
1246
1245
  });
1247
1246
  return { store: wrappedStore, node: node };
@@ -2154,7 +2153,6 @@ export {
2154
2153
  NoOwnerError,
2155
2154
  NotReadyError,
2156
2155
  SUPPORTS_PROXY,
2157
- createAsync,
2158
2156
  createBoundary,
2159
2157
  createContext,
2160
2158
  createEffect,
@@ -2179,6 +2177,7 @@ export {
2179
2177
  getOwner,
2180
2178
  isEqual,
2181
2179
  isPending,
2180
+ isRefreshing,
2182
2181
  isWrappable,
2183
2182
  mapArray,
2184
2183
  merge,
@@ -2187,6 +2186,7 @@ export {
2187
2186
  onSettled,
2188
2187
  pending,
2189
2188
  reconcile,
2189
+ refresh,
2190
2190
  repeat,
2191
2191
  resolve,
2192
2192
  runWithOwner,