@solidjs/signals 2.0.0-beta.12 → 2.0.0-beta.13

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/README.md CHANGED
@@ -107,8 +107,9 @@ const data = createMemo(async () => {
107
107
  return response.json();
108
108
  });
109
109
 
110
- // Check async state
111
- isPending(data); // true while loading
110
+ // Check async state during revalidation
111
+ isPending(data); // true while stale data is visible and newer data is pending
112
+ isPending(data, true); // follows the Loading path for render guards
112
113
  latest(data); // last resolved value
113
114
  ```
114
115
 
@@ -183,7 +184,7 @@ import { createErrorBoundary, createLoadingBoundary } from "@solidjs/signals";
183
184
 
184
185
  createErrorBoundary(
185
186
  () => riskyComputation(),
186
- (error, reset) => handleError(error)
187
+ (error, reset) => handleError(error())
187
188
  );
188
189
 
189
190
  createLoadingBoundary(
@@ -223,7 +224,7 @@ createRoot(dispose => {
223
224
  | ------------------------ | ------------------------------------------------------------------ |
224
225
  | `flush()` | Process all pending updates |
225
226
  | `untrack(fn)` | Run `fn` without tracking dependencies |
226
- | `isPending(accessor)` | Check if an async accessor is loading |
227
+ | `isPending(accessor)` | Check if an async accessor is revalidating stale data |
227
228
  | `latest(accessor)` | Get the last resolved value of an async accessor |
228
229
  | `refresh(accessor)` | Re-trigger an async computation |
229
230
  | `isRefreshing(accessor)` | Check if an async accessor is refreshing |
package/dist/dev.js CHANGED
@@ -1469,6 +1469,7 @@ let foundPending = false;
1469
1469
  let latestReadActive = false;
1470
1470
  let context = null;
1471
1471
  let currentOptimisticLane = null;
1472
+ let pendingCheckLoadingPath = false;
1472
1473
  let snapshotCaptureActive = false;
1473
1474
  let snapshotSources = null;
1474
1475
  function ownerInSnapshotScope(owner) {
@@ -1930,6 +1931,18 @@ function read(el) {
1930
1931
  const firewall = el._firewall;
1931
1932
  const prevCheck = pendingCheckActive;
1932
1933
  pendingCheckActive = false;
1934
+ const owner = firewall || el;
1935
+ if (
1936
+ pendingCheckLoadingPath &&
1937
+ owner._statusFlags & STATUS_PENDING &&
1938
+ owner._statusFlags & STATUS_UNINITIALIZED
1939
+ ) {
1940
+ let c = context;
1941
+ if (c?._root) c = c._parentComputed;
1942
+ if (c && tracking) link(el, c);
1943
+ pendingCheckActive = prevCheck;
1944
+ throw owner._error;
1945
+ }
1933
1946
  if (firewall && el._overrideValue !== undefined) {
1934
1947
  if (
1935
1948
  el._overrideValue !== NOT_PENDING &&
@@ -2296,18 +2309,23 @@ function latest(fn) {
2296
2309
  latestReadActive = prevLatest;
2297
2310
  }
2298
2311
  }
2299
- function isPending(fn) {
2312
+ function isPending(fn, loading) {
2300
2313
  const prevPendingCheck = pendingCheckActive;
2314
+ const prevPendingCheckLoadingPath = pendingCheckLoadingPath;
2301
2315
  const prevFoundPending = foundPending;
2316
+ const checkLoading = loading === true;
2302
2317
  pendingCheckActive = true;
2318
+ pendingCheckLoadingPath = checkLoading;
2303
2319
  foundPending = false;
2304
2320
  try {
2305
2321
  fn();
2306
2322
  return foundPending;
2307
- } catch {
2323
+ } catch (e) {
2324
+ if (checkLoading && e instanceof NotReadyError) throw e;
2308
2325
  return foundPending;
2309
2326
  } finally {
2310
2327
  pendingCheckActive = prevPendingCheck;
2328
+ pendingCheckLoadingPath = prevPendingCheckLoadingPath;
2311
2329
  foundPending = prevFoundPending;
2312
2330
  }
2313
2331
  }
@@ -4356,6 +4374,7 @@ class CollectionQueue extends Queue {
4356
4374
  _tree;
4357
4375
  _pending = true;
4358
4376
  _disabled = signal(false, { ownedWrite: true, _noSnapshot: true });
4377
+ _error;
4359
4378
  _collapsed = signal(false, { ownedWrite: true, _noSnapshot: true });
4360
4379
  _revealController;
4361
4380
  _initialized = false;
@@ -4397,6 +4416,9 @@ class CollectionQueue extends Queue {
4397
4416
  const wasEmpty = this._sources.size === 0;
4398
4417
  this._sources.add(source);
4399
4418
  if (wasEmpty) setSignal(this._disabled, true);
4419
+ if (this._collectionType & STATUS_ERROR) {
4420
+ setSignal(this._error, source._error?.cause ?? source._error);
4421
+ }
4400
4422
  }
4401
4423
  }
4402
4424
  type &= ~this._collectionType;
@@ -4450,6 +4472,8 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
4450
4472
  const owner = createOwner();
4451
4473
  if (_revealUsed) setContext(RevealControllerContext, null, owner);
4452
4474
  const queue = new CollectionQueue(type);
4475
+ if (type === STATUS_ERROR)
4476
+ queue._error = signal(undefined, { ownedWrite: true, _noSnapshot: true });
4453
4477
  if (onFn) queue._onFn = onFn;
4454
4478
  const tree = (queue._tree = createBoundChildren(owner, fn, queue, type));
4455
4479
  untrack(() => {
@@ -4485,14 +4509,12 @@ function createLoadingBoundary(fn, fallback, options) {
4485
4509
  return createCollectionBoundary(STATUS_PENDING, fn, () => fallback(), options?.on);
4486
4510
  }
4487
4511
  function createErrorBoundary(fn, fallback) {
4488
- return createCollectionBoundary(STATUS_ERROR, fn, queue => {
4489
- let source = queue._sources.values().next().value;
4490
- const error = source._error?.cause ?? source._error;
4491
- return fallback(error, () => {
4512
+ return createCollectionBoundary(STATUS_ERROR, fn, queue =>
4513
+ fallback(accessor(queue._error), () => {
4492
4514
  for (const source of queue._sources) recompute(source);
4493
4515
  schedule();
4494
- });
4495
- });
4516
+ })
4517
+ );
4496
4518
  }
4497
4519
  function createRevealOrder(fn, options) {
4498
4520
  _revealUsed = true;