solid-js 1.1.5 → 1.1.6-beta.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.cjs CHANGED
@@ -145,7 +145,6 @@ const UNOWNED = {
145
145
  context: null,
146
146
  owner: null
147
147
  };
148
- const [transPending, setTransPending] = /*@__PURE__*/createSignal(false);
149
148
  var Owner = null;
150
149
  let Transition = null;
151
150
  let Scheduler = null;
@@ -155,6 +154,7 @@ let Updates = null;
155
154
  let Effects = null;
156
155
  let ExecCount = 0;
157
156
  let rootCount = 0;
157
+ const [transPending, setTransPending] = /*@__PURE__*/createSignal(false);
158
158
  function createRoot(fn, detachedOwner) {
159
159
  detachedOwner && (Owner = detachedOwner);
160
160
  const listener = Listener,
@@ -186,12 +186,24 @@ function createSignal(value, options) {
186
186
  pending: NOTPENDING,
187
187
  comparator: options.equals || undefined
188
188
  };
189
+ if (Transition && Transition.running) Transition.sources.add(s);
189
190
  if (!options.internal) s.name = registerGraph(options.name || hashValue(value), s);
190
- return [readSignal.bind(s), value => {
191
- if (typeof value === "function") {
192
- if (Transition && Transition.running && Transition.sources.has(s)) value = value(s.pending !== NOTPENDING ? s.pending : s.tValue);else value = value(s.pending !== NOTPENDING ? s.pending : s.value);
191
+ return [() => {
192
+ let sig = s;
193
+ Transition && Transition.running && (sig = Transition.lookup.get(s) || sig);
194
+ if (Listener !== null) logRead(sig, Listener);
195
+ return sig.value;
196
+ }, value => {
197
+ let sig = s;
198
+ if (Transition) {
199
+ if (Transition.running && !(sig = Transition.lookup.get(s))) {
200
+ sig = forkSource(s);
201
+ } else if (!Transition.running) {
202
+ const other = Transition.lookup.get(s);
203
+ if (other) writeSignal(other, value);
204
+ }
193
205
  }
194
- return writeSignal(s, value);
206
+ return writeSignal(sig, value);
195
207
  }];
196
208
  }
197
209
  function createComputed(fn, value, options) {
@@ -216,9 +228,20 @@ function createMemo(fn, value, options) {
216
228
  c.observerSlots = null;
217
229
  c.comparator = options.equals || undefined;
218
230
  updateComputation(c);
219
- return readSignal.bind(c);
231
+ return () => {
232
+ let sig = c;
233
+ Transition && Transition.running && (sig = Transition.lookup.get(c) || sig);
234
+ if (c.state && c.sources) {
235
+ const updates = Updates;
236
+ Updates = null;
237
+ c.state === STALE ? updateComputation(c) : lookDownstream(c);
238
+ Updates = updates;
239
+ }
240
+ if (Listener !== null) logRead(sig, Listener);
241
+ return sig.value;
242
+ };
220
243
  }
221
- function createResource(source, fetcher, options = {}) {
244
+ function createResource(source, fetcher, options) {
222
245
  if (arguments.length === 2) {
223
246
  if (typeof fetcher === "object") {
224
247
  options = fetcher;
@@ -230,7 +253,7 @@ function createResource(source, fetcher, options = {}) {
230
253
  source = true;
231
254
  }
232
255
  const contexts = new Set(),
233
- [s, set] = createSignal(options.initialValue),
256
+ [s, set] = createSignal(options?.initialValue),
234
257
  [track, trigger] = createSignal(undefined, {
235
258
  equals: false
236
259
  }),
@@ -351,8 +374,9 @@ function createDeferred(source, options) {
351
374
  }
352
375
  function createSelector(source, fn = equalFn, options) {
353
376
  const subs = new Map();
377
+ let current;
354
378
  const node = createComputation(p => {
355
- const v = source();
379
+ const v = current = source();
356
380
  for (const key of subs.keys()) if (fn(key, v) || p !== undefined && fn(key, p)) {
357
381
  const l = subs.get(key);
358
382
  for (const c of l.values()) {
@@ -368,11 +392,9 @@ function createSelector(source, fn = equalFn, options) {
368
392
  if (listener = Listener) {
369
393
  let l;
370
394
  if (l = subs.get(key)) l.add(listener);else subs.set(key, l = new Set([listener]));
371
- onCleanup(() => {
372
- l.size > 1 ? l.delete(listener) : subs.delete(key);
373
- });
395
+ onCleanup(() => l.size > 1 ? l.delete(listener) : subs.delete(key));
374
396
  }
375
- return fn(key, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value);
397
+ return fn(key, current);
376
398
  };
377
399
  }
378
400
  function batch(fn) {
@@ -385,12 +407,12 @@ function batch(fn) {
385
407
  Pending = null;
386
408
  }
387
409
  runUpdates(() => {
388
- for (let i = 0; i < q.length; i += 1) {
410
+ for (let i = 0; i < q.length; i++) {
389
411
  const data = q[i];
390
412
  if (data.pending !== NOTPENDING) {
391
413
  const pending = data.pending;
392
414
  data.pending = NOTPENDING;
393
- writeSignal(data, pending);
415
+ writeSource(data, pending);
394
416
  }
395
417
  }
396
418
  }, false);
@@ -455,27 +477,29 @@ function enableScheduling(scheduler = requestCallback) {
455
477
  Scheduler = scheduler;
456
478
  }
457
479
  function startTransition(fn, cb) {
458
- if (Scheduler || SuspenseContext) {
459
- Transition || (Transition = {
460
- sources: new Set(),
461
- effects: [],
462
- promises: new Set(),
463
- disposed: new Set(),
464
- queue: new Set(),
465
- running: true,
466
- cb: []
467
- });
468
- cb && Transition.cb.push(cb);
469
- Transition.running = true;
470
- }
471
- batch(fn);
472
- if (!Scheduler && !SuspenseContext && cb) cb();
480
+ queueMicrotask(() => {
481
+ if (Scheduler || SuspenseContext) {
482
+ Transition || (Transition = {
483
+ sources: new Set(),
484
+ lookup: new Map(),
485
+ updated: new Set(),
486
+ effects: [],
487
+ promises: new Set(),
488
+ queue: new Set(),
489
+ running: true,
490
+ cb: []
491
+ });
492
+ cb && Transition.cb.push(cb);
493
+ Transition.running = true;
494
+ }
495
+ batch(fn);
496
+ if (!Scheduler && !SuspenseContext && cb) cb();
497
+ });
473
498
  }
474
499
  function useTransition() {
475
500
  return [transPending, startTransition];
476
501
  }
477
502
  function resumeEffects(e) {
478
- Transition && (Transition.running = true);
479
503
  Effects.push.apply(Effects, e);
480
504
  e.length = 0;
481
505
  }
@@ -487,7 +511,7 @@ function devComponent(Comp, props) {
487
511
  c.state = 0;
488
512
  c.componentName = Comp.name;
489
513
  updateComputation(c);
490
- return c.tValue !== undefined ? c.tValue : c.value;
514
+ return c.value;
491
515
  }
492
516
  function hashValue(v) {
493
517
  const s = new Set();
@@ -546,61 +570,44 @@ let SuspenseContext;
546
570
  function getSuspenseContext() {
547
571
  return SuspenseContext || (SuspenseContext = createContext({}));
548
572
  }
549
- function readSignal() {
550
- if (this.state && this.sources) {
551
- const updates = Updates;
552
- Updates = null;
553
- this.state === STALE || Transition && Transition.running && this.tState ? updateComputation(this) : lookDownstream(this);
554
- Updates = updates;
573
+ function logRead(node, to) {
574
+ const sSlot = node.observers ? node.observers.length : 0;
575
+ if (!to.sources) {
576
+ to.sources = [node];
577
+ to.sourceSlots = [sSlot];
578
+ } else {
579
+ to.sources.push(node);
580
+ to.sourceSlots.push(sSlot);
555
581
  }
556
- if (Listener) {
557
- const sSlot = this.observers ? this.observers.length : 0;
558
- if (!Listener.sources) {
559
- Listener.sources = [this];
560
- Listener.sourceSlots = [sSlot];
561
- } else {
562
- Listener.sources.push(this);
563
- Listener.sourceSlots.push(sSlot);
564
- }
565
- if (!this.observers) {
566
- this.observers = [Listener];
567
- this.observerSlots = [Listener.sources.length - 1];
568
- } else {
569
- this.observers.push(Listener);
570
- this.observerSlots.push(Listener.sources.length - 1);
571
- }
582
+ if (!node.observers) {
583
+ node.observers = [to];
584
+ node.observerSlots = [to.sources.length - 1];
585
+ } else {
586
+ node.observers.push(to);
587
+ node.observerSlots.push(to.sources.length - 1);
572
588
  }
573
- if (Transition && Transition.running && Transition.sources.has(this)) return this.tValue;
574
- return this.value;
575
- }
576
- function writeSignal(node, value, isComp) {
577
- if (node.comparator) {
578
- if (Transition && Transition.running && Transition.sources.has(node)) {
579
- if (node.comparator(node.tValue, value)) return value;
580
- } else if (node.comparator(node.value, value)) return value;
589
+ }
590
+ function writeSignal(node, value) {
591
+ if (typeof value === "function") {
592
+ value = value(node.pending !== NOTPENDING ? node.pending : node.value);
581
593
  }
594
+ return writeSource(node, value);
595
+ }
596
+ function writeSource(node, value) {
597
+ if (node.comparator && node.comparator(node.value, value)) return value;
582
598
  if (Pending) {
583
599
  if (node.pending === NOTPENDING) Pending.push(node);
584
600
  node.pending = value;
585
601
  return value;
586
602
  }
587
- let TransitionRunning = false;
588
- if (Transition) {
589
- TransitionRunning = Transition.running;
590
- if (TransitionRunning || !isComp && Transition.sources.has(node)) {
591
- Transition.sources.add(node);
592
- node.tValue = value;
593
- }
594
- if (!TransitionRunning) node.value = value;
595
- } else node.value = value;
603
+ node.value = value;
596
604
  if (node.observers && node.observers.length) {
597
605
  runUpdates(() => {
598
- for (let i = 0; i < node.observers.length; i += 1) {
606
+ for (let i = 0; i < node.observers.length; i++) {
599
607
  const o = node.observers[i];
600
- if (TransitionRunning && Transition.disposed.has(o)) continue;
601
608
  if (o.pure) Updates.push(o);else Effects.push(o);
602
- if (o.observers && (TransitionRunning && !o.tState || !TransitionRunning && !o.state)) markUpstream(o);
603
- if (TransitionRunning) o.tState = STALE;else o.state = STALE;
609
+ if (o.observers && !o.state) markUpstream(o);
610
+ o.state = STALE;
604
611
  }
605
612
  if (Updates.length > 10e5) {
606
613
  Updates = [];
@@ -613,17 +620,21 @@ function writeSignal(node, value, isComp) {
613
620
  }
614
621
  function updateComputation(node) {
615
622
  if (!node.fn) return;
623
+ if (Transition && Transition.sources.has(node)) {
624
+ Transition.updated.add(node);
625
+ if (!Transition.running) {
626
+ return queueMicrotask(() => runUpdates(() => {
627
+ Transition.running = true;
628
+ updateComputation(node);
629
+ }, false));
630
+ }
631
+ }
616
632
  cleanNode(node);
617
633
  const owner = Owner,
618
634
  listener = Listener,
619
635
  time = ExecCount;
620
636
  Listener = Owner = node;
621
637
  runComputation(node, node.value, time);
622
- if (Transition && !Transition.running && Transition.sources.has(node)) {
623
- Transition.running = true;
624
- runComputation(node, node.tValue, time);
625
- Transition.running = false;
626
- }
627
638
  Listener = listener;
628
639
  Owner = owner;
629
640
  }
@@ -636,10 +647,7 @@ function runComputation(node, value, time) {
636
647
  }
637
648
  if (!node.updatedAt || node.updatedAt <= time) {
638
649
  if (node.observers && node.observers.length) {
639
- writeSignal(node, nextValue, true);
640
- } else if (Transition && Transition.running && node.pure) {
641
- Transition.sources.add(node);
642
- node.tValue = nextValue;
650
+ writeSource(node, nextValue);
643
651
  } else node.value = nextValue;
644
652
  node.updatedAt = time;
645
653
  }
@@ -648,7 +656,7 @@ function createComputation(fn, init, pure, state = STALE, options) {
648
656
  const c = {
649
657
  fn,
650
658
  state: state,
651
- updatedAt: null,
659
+ updatedAt: 0,
652
660
  owned: null,
653
661
  sources: null,
654
662
  sourceSlots: null,
@@ -658,42 +666,25 @@ function createComputation(fn, init, pure, state = STALE, options) {
658
666
  context: null,
659
667
  pure
660
668
  };
661
- if (Transition && Transition.running) {
662
- c.state = 0;
663
- c.tState = state;
664
- }
665
669
  if (Owner === null) console.warn("computations created outside a `createRoot` or `render` will never be disposed");else if (Owner !== UNOWNED) {
666
- if (Transition && Transition.running && Owner.pure) {
667
- if (!Owner.tOwned) Owner.tOwned = [c];else Owner.tOwned.push(c);
668
- } else {
669
- if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
670
- }
671
- c.name = options && options.name || `${Owner.name || "c"}-${(Owner.owned || Owner.tOwned).length}`;
670
+ if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
671
+ c.name = options && options.name || `${Owner.name || "c"}-${Owner.owned.length}`;
672
672
  }
673
+ if (Transition && Transition.running) Transition.sources.add(c);
673
674
  return c;
674
675
  }
675
676
  function runTop(node) {
676
- const runningTransition = Transition && Transition.running;
677
- if (!runningTransition && node.state !== STALE) return node.state = 0;
678
- if (runningTransition && node.tState !== STALE) return node.tState = 0;
677
+ if (node.state !== STALE) return node.state = 0;
679
678
  if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node);
680
679
  const ancestors = [node];
681
680
  while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) {
682
- if (runningTransition && Transition.disposed.has(node)) return;
683
- if (node.state || runningTransition && node.tState) ancestors.push(node);
681
+ if (node.state) ancestors.push(node);
684
682
  }
685
683
  for (let i = ancestors.length - 1; i >= 0; i--) {
686
684
  node = ancestors[i];
687
- if (runningTransition) {
688
- let top = node,
689
- prev = ancestors[i + 1];
690
- while ((top = top.owner) && top !== prev) {
691
- if (Transition.disposed.has(top)) return;
692
- }
693
- }
694
- if (node.state === STALE || runningTransition && node.tState === STALE) {
685
+ if (node.state === STALE) {
695
686
  updateComputation(node);
696
- } else if (node.state === PENDING || runningTransition && node.tState === PENDING) {
687
+ } else if (node.state === PENDING) {
697
688
  const updates = Updates;
698
689
  Updates = null;
699
690
  lookDownstream(node);
@@ -730,24 +721,11 @@ function completeUpdates(wait) {
730
721
  setTransPending(true);
731
722
  return;
732
723
  }
733
- const sources = Transition.sources;
724
+ const t = Transition;
734
725
  cbs = Transition.cb;
735
- Effects.forEach(e => {
736
- "tState" in e && (e.state = e.tState);
737
- delete e.tState;
738
- });
739
726
  Transition = null;
740
727
  batch(() => {
741
- sources.forEach(v => {
742
- v.value = v.tValue;
743
- if (v.owned) {
744
- for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]);
745
- }
746
- if (v.tOwned) v.owned = v.tOwned;
747
- delete v.tValue;
748
- delete v.tOwned;
749
- v.tState = 0;
750
- });
728
+ mergeTransition(t);
751
729
  setTransPending(false);
752
730
  });
753
731
  }
@@ -797,24 +775,75 @@ function runUserEffects(queue) {
797
775
  }
798
776
  function lookDownstream(node) {
799
777
  node.state = 0;
800
- for (let i = 0; i < node.sources.length; i += 1) {
778
+ for (let i = 0; i < node.sources.length; i++) {
801
779
  const source = node.sources[i];
802
780
  if (source.sources) {
803
- if (source.state === STALE || Transition && Transition.running && source.tState) runTop(source);else if (source.state === PENDING) lookDownstream(source);
781
+ if (source.state === STALE) runTop(source);else if (source.state === PENDING) lookDownstream(source);
804
782
  }
805
783
  }
806
784
  }
807
785
  function markUpstream(node) {
808
- const runningTransition = Transition && Transition.running;
809
- for (let i = 0; i < node.observers.length; i += 1) {
786
+ for (let i = 0; i < node.observers.length; i++) {
810
787
  const o = node.observers[i];
811
- if (!o.state || runningTransition && !o.tState) {
812
- if (runningTransition) o.tState = PENDING;else o.state = PENDING;
788
+ if (!o.state) {
789
+ o.state = PENDING;
813
790
  if (o.pure) Updates.push(o);else Effects.push(o);
814
791
  o.observers && markUpstream(o);
815
792
  }
816
793
  }
817
794
  }
795
+ function forkSource(s, p, slot) {
796
+ let fork;
797
+ if (!(fork = Transition.lookup.get(s) || Transition.sources.has(s) && s)) {
798
+ Transition.lookup.set(s, fork = { ...s
799
+ });
800
+ Transition.sources.add(fork);
801
+ if (fork.observers) {
802
+ fork.observers = [...new Set(fork.observers)];
803
+ fork.observerSlots = [];
804
+ fork.observers.forEach((o, i) => forkSource(o, fork, i));
805
+ }
806
+ if (fork.sources) {
807
+ fork.sources = [p];
808
+ fork.sourceSlots = [slot];
809
+ replaceObservers(fork, p, slot, 0);
810
+ }
811
+ fork.owned && (fork.owned = null);
812
+ fork.cleanups && (fork.cleanups = null);
813
+ } else if ("sources" in fork) {
814
+ fork.sources.push(p);
815
+ fork.sourceSlots.push(slot);
816
+ replaceObservers(fork, p, slot, fork.sources.length - 1);
817
+ }
818
+ return fork;
819
+ }
820
+ function replaceObservers(node, source, slot, sourceSlot) {
821
+ source.observers || (source.observers = []);
822
+ source.observerSlots || (source.observerSlots = []);
823
+ source.observers[slot] = node;
824
+ source.observerSlots[slot] = sourceSlot;
825
+ }
826
+ function mergeTransition(transition) {
827
+ const reverse = new Map(Array.from(transition.lookup, entry => [entry[1], entry[0]]));
828
+ transition.lookup.forEach((fork, og) => {
829
+ if ("sources" in fork && (fork.state || transition.updated.has(fork))) cleanNode(og);
830
+ });
831
+ transition.lookup.forEach((fork, og) => {
832
+ if ("sources" in fork && !fork.state && !transition.updated.has(fork)) return;
833
+ transition.updated.delete(fork);
834
+ Object.assign(og, fork);
835
+ if (og.sources) {
836
+ og.sourceSlots.forEach((slot, i) => {
837
+ og.sources[i] = reverse.get(og.sources[i]) || og.sources[i];
838
+ replaceObservers(og, og.sources[i], slot, i);
839
+ });
840
+ }
841
+ });
842
+ Effects.forEach((e, i) => {
843
+ const replace = reverse.get(e);
844
+ if (replace) Effects[i] = replace;
845
+ });
846
+ }
818
847
  function cleanNode(node) {
819
848
  let i;
820
849
  if (node.sources) {
@@ -833,13 +862,7 @@ function cleanNode(node) {
833
862
  }
834
863
  }
835
864
  }
836
- if (Transition && Transition.running && node.pure) {
837
- if (node.tOwned) {
838
- for (i = 0; i < node.tOwned.length; i++) cleanNode(node.tOwned[i]);
839
- delete node.tOwned;
840
- }
841
- reset(node, true);
842
- } else if (node.owned) {
865
+ if (node.owned) {
843
866
  for (i = 0; i < node.owned.length; i++) cleanNode(node.owned[i]);
844
867
  node.owned = null;
845
868
  }
@@ -847,18 +870,9 @@ function cleanNode(node) {
847
870
  for (i = 0; i < node.cleanups.length; i++) node.cleanups[i]();
848
871
  node.cleanups = null;
849
872
  }
850
- if (Transition && Transition.running) node.tState = 0;else node.state = 0;
873
+ node.state = 0;
851
874
  node.context = null;
852
875
  }
853
- function reset(node, top) {
854
- if (!top) {
855
- node.tState = 0;
856
- Transition.disposed.add(node);
857
- }
858
- if (node.owned) {
859
- for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]);
860
- }
861
- }
862
876
  function handleError(err) {
863
877
  const fns = ERROR && lookup(Owner, ERROR);
864
878
  if (!fns) throw err;