@solidjs/signals 0.9.9 → 0.9.11

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
@@ -158,12 +158,15 @@ function getOrCreateLane(signal) {
158
158
  if (lane) {
159
159
  return findLane(lane);
160
160
  }
161
+ const parentSource = signal._parentSource;
162
+ const parentLane = parentSource?._optimisticLane ? findLane(parentSource._optimisticLane) : null;
161
163
  lane = {
162
164
  _source: signal,
163
165
  _pendingAsync: new Set(),
164
166
  _effectQueues: [[], []],
165
167
  _mergedInto: null,
166
- _transition: activeTransition
168
+ _transition: activeTransition,
169
+ _parentLane: parentLane
167
170
  };
168
171
  signalLanes.set(signal, lane);
169
172
  activeLanes.add(lane);
@@ -209,7 +212,10 @@ function assignOrMergeLane(el, sourceLane) {
209
212
  const existingRoot = findLane(existing);
210
213
  if (activeLanes.has(existingRoot)) {
211
214
  if (existingRoot !== sourceRoot && !hasActiveOverride(el)) {
212
- mergeLanes(sourceRoot, existingRoot);
215
+ if (sourceRoot._parentLane && findLane(sourceRoot._parentLane) === existingRoot) {
216
+ el._optimisticLane = sourceLane;
217
+ } else if (existingRoot._parentLane && findLane(existingRoot._parentLane) === sourceRoot);
218
+ else mergeLanes(sourceRoot, existingRoot);
213
219
  }
214
220
  return;
215
221
  }
@@ -531,7 +537,8 @@ function transitionComplete(transition) {
531
537
  if (transition._actions.length) return false;
532
538
  let done = true;
533
539
  for (let i = 0; i < transition._asyncNodes.length; i++) {
534
- if (transition._asyncNodes[i]._statusFlags & STATUS_PENDING) {
540
+ const node = transition._asyncNodes[i];
541
+ if (node._statusFlags & STATUS_PENDING && node._error?._source === node) {
535
542
  done = false;
536
543
  break;
537
544
  }
@@ -645,13 +652,17 @@ function recompute(el, create = false) {
645
652
  value = handleAsync(el, el._fn(value));
646
653
  clearStatus(el);
647
654
  const resolvedLane = resolveLane(el);
648
- if (resolvedLane) resolvedLane._pendingAsync.delete(el);
655
+ if (resolvedLane) {
656
+ resolvedLane._pendingAsync.delete(el);
657
+ updatePendingSignal(resolvedLane._source);
658
+ }
649
659
  } catch (e) {
650
660
  if (e instanceof NotReadyError && currentOptimisticLane) {
651
661
  const lane = findLane(currentOptimisticLane);
652
662
  if (lane._source !== el) {
653
663
  lane._pendingAsync.add(el);
654
664
  el._optimisticLane = lane;
665
+ updatePendingSignal(lane._source);
655
666
  }
656
667
  }
657
668
  notifyStatus(
@@ -1106,12 +1117,24 @@ function optimisticComputed(fn, initialValue, options) {
1106
1117
  function getPendingSignal(el) {
1107
1118
  if (!el._pendingSignal) {
1108
1119
  el._pendingSignal = optimisticSignal(false, { pureWrite: true });
1120
+ if (el._parentSource) {
1121
+ el._pendingSignal._parentSource = el;
1122
+ }
1109
1123
  if (computePendingState(el)) setSignal(el._pendingSignal, true);
1110
1124
  }
1111
1125
  return el._pendingSignal;
1112
1126
  }
1113
1127
  function computePendingState(el) {
1114
1128
  const comp = el;
1129
+ if (el._optimistic && el._pendingValue !== NOT_PENDING) {
1130
+ if (comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED))
1131
+ return true;
1132
+ if (el._parentSource) {
1133
+ const lane = el._optimisticLane ? findLane(el._optimisticLane) : null;
1134
+ return !!(lane && lane._pendingAsync.size > 0);
1135
+ }
1136
+ return true;
1137
+ }
1115
1138
  if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
1116
1139
  return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
1117
1140
  }
@@ -1119,10 +1142,14 @@ function getPendingValueComputed(el) {
1119
1142
  if (!el._pendingValueComputed) {
1120
1143
  const prevPending = pendingReadActive;
1121
1144
  pendingReadActive = false;
1145
+ const prevCheck = pendingCheckActive;
1146
+ pendingCheckActive = false;
1122
1147
  const prevContext = context;
1123
1148
  context = null;
1124
1149
  el._pendingValueComputed = optimisticComputed(() => read(el));
1150
+ el._pendingValueComputed._parentSource = el;
1125
1151
  context = prevContext;
1152
+ pendingCheckActive = prevCheck;
1126
1153
  pendingReadActive = prevPending;
1127
1154
  }
1128
1155
  return el._pendingValueComputed;
@@ -1158,6 +1185,22 @@ function untrack(fn) {
1158
1185
  }
1159
1186
  }
1160
1187
  function read(el) {
1188
+ if (pendingReadActive) {
1189
+ const pendingComputed = getPendingValueComputed(el);
1190
+ const prevPending = pendingReadActive;
1191
+ pendingReadActive = false;
1192
+ const value = read(pendingComputed);
1193
+ pendingReadActive = prevPending;
1194
+ if (pendingComputed._statusFlags & STATUS_PENDING) return el._value;
1195
+ if (stale && currentOptimisticLane && pendingComputed._optimisticLane) {
1196
+ const pcLane = findLane(pendingComputed._optimisticLane);
1197
+ const curLane = findLane(currentOptimisticLane);
1198
+ if (pcLane !== curLane && pcLane._pendingAsync.size > 0) {
1199
+ return el._value;
1200
+ }
1201
+ }
1202
+ return value;
1203
+ }
1161
1204
  if (pendingCheckActive) {
1162
1205
  const target = el._firewall || el;
1163
1206
  const pendingSig = getPendingSignal(target);
@@ -1169,15 +1212,6 @@ function read(el) {
1169
1212
  pendingCheckActive = prevCheck;
1170
1213
  return el._value;
1171
1214
  }
1172
- if (pendingReadActive) {
1173
- const pendingComputed = getPendingValueComputed(el);
1174
- const prevPending = pendingReadActive;
1175
- pendingReadActive = false;
1176
- const value = read(pendingComputed);
1177
- pendingReadActive = prevPending;
1178
- if (pendingComputed._statusFlags & STATUS_PENDING) return el._value;
1179
- return value;
1180
- }
1181
1215
  let c = context;
1182
1216
  if (c?._root) c = c._parentComputed;
1183
1217
  if (refreshing && el._fn) recompute(el);
@@ -1709,6 +1743,7 @@ function applyState(next, state, keyFn, all) {
1709
1743
  if (
1710
1744
  !previousValue ||
1711
1745
  !isWrappable(previousValue) ||
1746
+ !isWrappable(nextValue) ||
1712
1747
  (keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
1713
1748
  ) {
1714
1749
  tracked && setSignal(tracked, void 0);