@solidjs/signals 0.0.8 → 0.0.9

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
@@ -27,8 +27,7 @@ var EffectError = class extends Error {
27
27
  var STATE_CLEAN = 0;
28
28
  var STATE_CHECK = 1;
29
29
  var STATE_DIRTY = 2;
30
- var STATE_UNINITIALIZED = 3;
31
- var STATE_DISPOSED = 4;
30
+ var STATE_DISPOSED = 3;
32
31
  var EFFECT_PURE = 0;
33
32
  var EFFECT_RENDER = 1;
34
33
  var EFFECT_USER = 2;
@@ -237,6 +236,8 @@ var ERROR_OFFSET = 0;
237
236
  var ERROR_BIT = 1 << ERROR_OFFSET;
238
237
  var LOADING_OFFSET = 1;
239
238
  var LOADING_BIT = 1 << LOADING_OFFSET;
239
+ var UNINITIALIZED_OFFSET = 2;
240
+ var UNINITIALIZED_BIT = 1 << UNINITIALIZED_OFFSET;
240
241
  var DEFAULT_FLAGS = ERROR_BIT;
241
242
 
242
243
  // src/core/core.ts
@@ -246,8 +247,9 @@ var newSources = null;
246
247
  var newSourcesIndex = 0;
247
248
  var newFlags = 0;
248
249
  var clock = 0;
249
- var syncResolve = false;
250
+ var notStale = false;
250
251
  var updateCheck = null;
252
+ var staleCheck = null;
251
253
  function getObserver() {
252
254
  return currentObserver;
253
255
  }
@@ -262,6 +264,7 @@ var Computation = class extends Owner {
262
264
  _sources = null;
263
265
  _observers = null;
264
266
  _value;
267
+ _error;
265
268
  _compute;
266
269
  // Used in __DEV__ mode, hopefully removed in production
267
270
  _name;
@@ -279,7 +282,8 @@ var Computation = class extends Owner {
279
282
  constructor(initialValue, compute2, options) {
280
283
  super(compute2 === null);
281
284
  this._compute = compute2;
282
- this._state = compute2 ? STATE_UNINITIALIZED : STATE_CLEAN;
285
+ this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
286
+ this._stateFlags = compute2 && initialValue === void 0 ? UNINITIALIZED_BIT : 0;
283
287
  this._value = initialValue;
284
288
  this._name = options?.name ?? (this._compute ? "computed" : "signal");
285
289
  if (options?.equals !== void 0)
@@ -294,7 +298,7 @@ var Computation = class extends Owner {
294
298
  track(this);
295
299
  newFlags |= this._stateFlags & ~currentMask;
296
300
  if (this._stateFlags & ERROR_BIT) {
297
- throw this._value;
301
+ throw this._error;
298
302
  } else {
299
303
  return this._value;
300
304
  }
@@ -317,9 +321,11 @@ var Computation = class extends Owner {
317
321
  if (this._compute && this._stateFlags & ERROR_BIT && this._time <= clock) {
318
322
  update(this);
319
323
  }
320
- if (!syncResolve && this.loading()) {
324
+ if ((notStale || this._stateFlags & UNINITIALIZED_BIT) && this.loading()) {
321
325
  throw new NotReadyError();
322
326
  }
327
+ if (staleCheck && this._stateFlags & LOADING_BIT)
328
+ staleCheck._value = true;
323
329
  return this._read();
324
330
  }
325
331
  /**
@@ -338,9 +344,11 @@ var Computation = class extends Owner {
338
344
  /** Update the computation with a new value. */
339
345
  write(value, flags = 0, raw = false) {
340
346
  const newValue = !raw && typeof value === "function" ? value(this._value) : value;
341
- const valueChanged = newValue !== UNCHANGED && (!!(flags & ERROR_BIT) || this._state === STATE_UNINITIALIZED || this._equals === false || !this._equals(this._value, newValue));
342
- if (valueChanged)
347
+ const valueChanged = newValue !== UNCHANGED && (!!(this._stateFlags & UNINITIALIZED_BIT) || this._equals === false || !this._equals(this._value, newValue));
348
+ if (valueChanged) {
343
349
  this._value = newValue;
350
+ this._error = void 0;
351
+ }
344
352
  const changedFlagsMask = this._stateFlags ^ flags, changedFlags = changedFlagsMask & flags;
345
353
  this._stateFlags = flags;
346
354
  this._time = clock + 1;
@@ -398,7 +406,8 @@ var Computation = class extends Owner {
398
406
  }
399
407
  }
400
408
  _setError(error) {
401
- this.write(error, this._stateFlags & ~LOADING_BIT | ERROR_BIT);
409
+ this._error = error;
410
+ this.write(UNCHANGED, this._stateFlags & ~LOADING_BIT | ERROR_BIT | UNINITIALIZED_BIT);
402
411
  }
403
412
  /**
404
413
  * This is the core part of the reactivity system, which makes sure that the values are updated
@@ -424,7 +433,7 @@ var Computation = class extends Owner {
424
433
  }
425
434
  }
426
435
  }
427
- if (this._state === STATE_DIRTY || this._state === STATE_UNINITIALIZED) {
436
+ if (this._state === STATE_DIRTY) {
428
437
  update(this);
429
438
  } else {
430
439
  this.write(UNCHANGED, observerFlags);
@@ -484,7 +493,7 @@ function update(node) {
484
493
  node.write(result, newFlags, true);
485
494
  } catch (error) {
486
495
  if (error instanceof NotReadyError) {
487
- node.write(UNCHANGED, newFlags | LOADING_BIT);
496
+ node.write(UNCHANGED, newFlags | LOADING_BIT | node._stateFlags & UNINITIALIZED_BIT);
488
497
  } else {
489
498
  node._setError(error);
490
499
  }
@@ -551,23 +560,27 @@ function hasUpdated(fn) {
551
560
  updateCheck = current;
552
561
  }
553
562
  }
554
- function isPending(fn) {
563
+ function isStale(fn) {
564
+ const current = staleCheck;
565
+ staleCheck = { _value: false };
555
566
  try {
556
- fn();
557
- return false;
558
- } catch (e) {
559
- return e instanceof NotReadyError;
567
+ latest(fn);
568
+ return staleCheck._value;
569
+ } catch {
570
+ } finally {
571
+ staleCheck = current;
560
572
  }
573
+ return false;
561
574
  }
562
- function resolveSync(fn) {
575
+ function latest(fn) {
563
576
  const prevFlags = newFlags;
564
- syncResolve = true;
577
+ const prevNotStale = notStale;
578
+ notStale = false;
565
579
  try {
566
580
  return fn();
567
- } catch {
568
581
  } finally {
569
582
  newFlags = prevFlags;
570
- syncResolve = false;
583
+ notStale = prevNotStale;
571
584
  }
572
585
  }
573
586
  function catchError(fn) {
@@ -579,16 +592,18 @@ function catchError(fn) {
579
592
  return e;
580
593
  }
581
594
  }
582
- function compute(owner, compute2, observer) {
583
- const prevOwner = setOwner(owner), prevObserver = currentObserver, prevMask = currentMask;
595
+ function compute(owner, fn, observer) {
596
+ const prevOwner = setOwner(owner), prevObserver = currentObserver, prevMask = currentMask, prevNotStale = notStale;
584
597
  currentObserver = observer;
585
598
  currentMask = observer?._handlerMask ?? DEFAULT_FLAGS;
599
+ notStale = true;
586
600
  try {
587
- return compute2(observer ? observer._value : void 0);
601
+ return fn(observer ? observer._value : void 0);
588
602
  } finally {
589
603
  setOwner(prevOwner);
590
604
  currentObserver = prevObserver;
591
605
  currentMask = prevMask;
606
+ notStale = prevNotStale;
592
607
  }
593
608
  }
594
609
 
@@ -695,7 +710,7 @@ function runEffectQueue(queue) {
695
710
  // src/core/effect.ts
696
711
  var Effect = class extends Computation {
697
712
  _effect;
698
- _error;
713
+ _onerror;
699
714
  _cleanup;
700
715
  _modified = false;
701
716
  _prevValue;
@@ -704,9 +719,12 @@ var Effect = class extends Computation {
704
719
  constructor(initialValue, compute2, effect, error, options) {
705
720
  super(initialValue, compute2, options);
706
721
  this._effect = effect;
707
- this._error = error;
722
+ this._onerror = error;
708
723
  this._prevValue = initialValue;
709
724
  this._type = options?.render ? EFFECT_RENDER : EFFECT_USER;
725
+ if (this._type === EFFECT_RENDER) {
726
+ this._compute = (p) => latest(() => compute2(p));
727
+ }
710
728
  this._queue = getOwner()?._queue || globalQueue;
711
729
  if (!options?.defer) {
712
730
  this._updateIfNecessary();
@@ -716,10 +734,12 @@ var Effect = class extends Computation {
716
734
  console.warn("Effects created outside a reactive context will never be disposed");
717
735
  }
718
736
  write(value, flags = 0) {
719
- const currentFlags = this._stateFlags;
720
- this._stateFlags = flags;
721
- if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
722
- this._queue._update?.(this);
737
+ if (this._state == STATE_DIRTY) {
738
+ const currentFlags = this._stateFlags;
739
+ this._stateFlags = flags;
740
+ if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
741
+ this._queue._update?.(this);
742
+ }
723
743
  }
724
744
  if (value === UNCHANGED)
725
745
  return this._value;
@@ -742,7 +762,7 @@ var Effect = class extends Computation {
742
762
  }
743
763
  if (this._type === EFFECT_USER) {
744
764
  try {
745
- return this._error ? this._cleanup = this._error(error) : console.error(new EffectError(this._effect, error));
765
+ return this._onerror ? this._cleanup = this._onerror(error) : console.error(new EffectError(this._effect, error));
746
766
  } catch (e) {
747
767
  error = e;
748
768
  }
@@ -754,7 +774,7 @@ var Effect = class extends Computation {
754
774
  return;
755
775
  this._effect = void 0;
756
776
  this._prevValue = void 0;
757
- this._error = void 0;
777
+ this._onerror = void 0;
758
778
  this._cleanup?.();
759
779
  this._cleanup = void 0;
760
780
  super._disposeNode();
@@ -790,6 +810,22 @@ var EagerComputation = class extends Computation {
790
810
  super._notify(state, skipQueue);
791
811
  }
792
812
  };
813
+ var ProjectionComputation = class extends Computation {
814
+ _queue;
815
+ constructor(compute2) {
816
+ super(null, compute2);
817
+ this._queue = getOwner()?._queue || globalQueue;
818
+ if (!this._parent)
819
+ console.warn("Eager Computations created outside a reactive context will never be disposed");
820
+ }
821
+ _notify(state, skipQueue) {
822
+ if (this._state >= state && !this._forceNotify)
823
+ return;
824
+ if (this._state === STATE_CLEAN && !skipQueue)
825
+ this._queue.enqueue(EFFECT_PURE, this);
826
+ super._notify(state, true);
827
+ }
828
+ };
793
829
 
794
830
  // src/core/suspense.ts
795
831
  var SuspenseQueue = class extends Queue {
@@ -869,13 +905,14 @@ function createMemo(compute2, value, options) {
869
905
  node = void 0;
870
906
  } else if (!node._parent && !node._observers?.length) {
871
907
  node.dispose();
872
- node._state = STATE_UNINITIALIZED;
908
+ node._state = STATE_DIRTY;
873
909
  }
874
910
  }
875
911
  return resolvedValue;
876
912
  };
877
913
  }
878
914
  function createAsync(compute2, value, options) {
915
+ let uninitialized = value === void 0;
879
916
  const lhs = new EagerComputation(
880
917
  {
881
918
  _value: value
@@ -902,14 +939,16 @@ function createAsync(compute2, value, options) {
902
939
  }
903
940
  return w.call(this);
904
941
  };
905
- signal.write(UNCHANGED, LOADING_BIT);
942
+ signal.write(UNCHANGED, LOADING_BIT | (uninitialized ? UNINITIALIZED_BIT : 0));
906
943
  if (isPromise) {
907
944
  source.then(
908
945
  (value3) => {
946
+ uninitialized = false;
909
947
  signal.write(value3, 0, true);
910
948
  },
911
949
  (error) => {
912
- signal.write(error, ERROR_BIT);
950
+ uninitialized = true;
951
+ signal._setError(error);
913
952
  }
914
953
  );
915
954
  } else {
@@ -1019,18 +1058,9 @@ function createReaction(effect, error, options) {
1019
1058
  }
1020
1059
 
1021
1060
  // src/store/projection.ts
1022
- var ProjectionComputation = class extends EagerComputation {
1023
- _notify(state, skipQueue) {
1024
- if (this._state >= state && !this._forceNotify)
1025
- return;
1026
- if (this._state === STATE_CLEAN && !skipQueue)
1027
- this._queue.enqueue(EFFECT_PURE, this);
1028
- super._notify(state, true);
1029
- }
1030
- };
1031
1061
  function createProjection(fn, initialValue = {}) {
1032
1062
  const [store, setStore] = createStore(initialValue);
1033
- const node = new ProjectionComputation(void 0, () => {
1063
+ const node = new ProjectionComputation(() => {
1034
1064
  setStore(fn);
1035
1065
  });
1036
1066
  const wrapped = /* @__PURE__ */ new WeakMap();
@@ -1676,4 +1706,4 @@ function compare(key, a, b) {
1676
1706
  return key ? key(a) === key(b) : true;
1677
1707
  }
1678
1708
 
1679
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, catchError, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createProjection, createReaction, createRenderEffect, createRoot, createSignal, createStore, createSuspense, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, resolveSync, runWithOwner, setContext, untrack, unwrap };
1709
+ export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, catchError, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createProjection, createReaction, createRenderEffect, createRoot, createSignal, createStore, createSuspense, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isStale, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithOwner, setContext, untrack, unwrap };