solid-js 1.1.2 → 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/solid.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;
@@ -154,6 +153,7 @@ let Pending = null;
154
153
  let Updates = null;
155
154
  let Effects = null;
156
155
  let ExecCount = 0;
156
+ const [transPending, setTransPending] = /*@__PURE__*/createSignal(false);
157
157
  function createRoot(fn, detachedOwner) {
158
158
  detachedOwner && (Owner = detachedOwner);
159
159
  const listener = Listener,
@@ -184,11 +184,23 @@ function createSignal(value, options) {
184
184
  pending: NOTPENDING,
185
185
  comparator: options.equals || undefined
186
186
  };
187
- return [readSignal.bind(s), value => {
188
- if (typeof value === "function") {
189
- 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);
187
+ if (Transition && Transition.running) Transition.sources.add(s);
188
+ return [() => {
189
+ let sig = s;
190
+ Transition && Transition.running && (sig = Transition.lookup.get(s) || sig);
191
+ if (Listener !== null) logRead(sig, Listener);
192
+ return sig.value;
193
+ }, value => {
194
+ let sig = s;
195
+ if (Transition) {
196
+ if (Transition.running && !(sig = Transition.lookup.get(s))) {
197
+ sig = forkSource(s);
198
+ } else if (!Transition.running) {
199
+ const other = Transition.lookup.get(s);
200
+ if (other) writeSignal(other, value);
201
+ }
190
202
  }
191
- return writeSignal(s, value);
203
+ return writeSignal(sig, value);
192
204
  }];
193
205
  }
194
206
  function createComputed(fn, value, options) {
@@ -213,9 +225,20 @@ function createMemo(fn, value, options) {
213
225
  c.observerSlots = null;
214
226
  c.comparator = options.equals || undefined;
215
227
  updateComputation(c);
216
- return readSignal.bind(c);
228
+ return () => {
229
+ let sig = c;
230
+ Transition && Transition.running && (sig = Transition.lookup.get(c) || sig);
231
+ if (c.state && c.sources) {
232
+ const updates = Updates;
233
+ Updates = null;
234
+ c.state === STALE ? updateComputation(c) : lookDownstream(c);
235
+ Updates = updates;
236
+ }
237
+ if (Listener !== null) logRead(sig, Listener);
238
+ return sig.value;
239
+ };
217
240
  }
218
- function createResource(source, fetcher, options = {}) {
241
+ function createResource(source, fetcher, options) {
219
242
  if (arguments.length === 2) {
220
243
  if (typeof fetcher === "object") {
221
244
  options = fetcher;
@@ -227,7 +250,7 @@ function createResource(source, fetcher, options = {}) {
227
250
  source = true;
228
251
  }
229
252
  const contexts = new Set(),
230
- [s, set] = createSignal(options.initialValue),
253
+ [s, set] = createSignal(options?.initialValue),
231
254
  [track, trigger] = createSignal(undefined, {
232
255
  equals: false
233
256
  }),
@@ -348,8 +371,9 @@ function createDeferred(source, options) {
348
371
  }
349
372
  function createSelector(source, fn = equalFn, options) {
350
373
  const subs = new Map();
374
+ let current;
351
375
  const node = createComputation(p => {
352
- const v = source();
376
+ const v = current = source();
353
377
  for (const key of subs.keys()) if (fn(key, v) || p !== undefined && fn(key, p)) {
354
378
  const l = subs.get(key);
355
379
  for (const c of l.values()) {
@@ -365,11 +389,9 @@ function createSelector(source, fn = equalFn, options) {
365
389
  if (listener = Listener) {
366
390
  let l;
367
391
  if (l = subs.get(key)) l.add(listener);else subs.set(key, l = new Set([listener]));
368
- onCleanup(() => {
369
- l.size > 1 ? l.delete(listener) : subs.delete(key);
370
- });
392
+ onCleanup(() => l.size > 1 ? l.delete(listener) : subs.delete(key));
371
393
  }
372
- return fn(key, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value);
394
+ return fn(key, current);
373
395
  };
374
396
  }
375
397
  function batch(fn) {
@@ -382,12 +404,12 @@ function batch(fn) {
382
404
  Pending = null;
383
405
  }
384
406
  runUpdates(() => {
385
- for (let i = 0; i < q.length; i += 1) {
407
+ for (let i = 0; i < q.length; i++) {
386
408
  const data = q[i];
387
409
  if (data.pending !== NOTPENDING) {
388
410
  const pending = data.pending;
389
411
  data.pending = NOTPENDING;
390
- writeSignal(data, pending);
412
+ writeSource(data, pending);
391
413
  }
392
414
  }
393
415
  }, false);
@@ -452,27 +474,29 @@ function enableScheduling(scheduler = requestCallback) {
452
474
  Scheduler = scheduler;
453
475
  }
454
476
  function startTransition(fn, cb) {
455
- if (Scheduler || SuspenseContext) {
456
- Transition || (Transition = {
457
- sources: new Set(),
458
- effects: [],
459
- promises: new Set(),
460
- disposed: new Set(),
461
- queue: new Set(),
462
- running: true,
463
- cb: []
464
- });
465
- cb && Transition.cb.push(cb);
466
- Transition.running = true;
467
- }
468
- batch(fn);
469
- if (!Scheduler && !SuspenseContext && cb) cb();
477
+ queueMicrotask(() => {
478
+ if (Scheduler || SuspenseContext) {
479
+ Transition || (Transition = {
480
+ sources: new Set(),
481
+ lookup: new Map(),
482
+ updated: new Set(),
483
+ effects: [],
484
+ promises: new Set(),
485
+ queue: new Set(),
486
+ running: true,
487
+ cb: []
488
+ });
489
+ cb && Transition.cb.push(cb);
490
+ Transition.running = true;
491
+ }
492
+ batch(fn);
493
+ if (!Scheduler && !SuspenseContext && cb) cb();
494
+ });
470
495
  }
471
496
  function useTransition() {
472
497
  return [transPending, startTransition];
473
498
  }
474
499
  function resumeEffects(e) {
475
- Transition && (Transition.running = true);
476
500
  Effects.push.apply(Effects, e);
477
501
  e.length = 0;
478
502
  }
@@ -495,61 +519,44 @@ let SuspenseContext;
495
519
  function getSuspenseContext() {
496
520
  return SuspenseContext || (SuspenseContext = createContext({}));
497
521
  }
498
- function readSignal() {
499
- if (this.state && this.sources) {
500
- const updates = Updates;
501
- Updates = null;
502
- this.state === STALE || Transition && Transition.running && this.tState ? updateComputation(this) : lookDownstream(this);
503
- Updates = updates;
522
+ function logRead(node, to) {
523
+ const sSlot = node.observers ? node.observers.length : 0;
524
+ if (!to.sources) {
525
+ to.sources = [node];
526
+ to.sourceSlots = [sSlot];
527
+ } else {
528
+ to.sources.push(node);
529
+ to.sourceSlots.push(sSlot);
504
530
  }
505
- if (Listener) {
506
- const sSlot = this.observers ? this.observers.length : 0;
507
- if (!Listener.sources) {
508
- Listener.sources = [this];
509
- Listener.sourceSlots = [sSlot];
510
- } else {
511
- Listener.sources.push(this);
512
- Listener.sourceSlots.push(sSlot);
513
- }
514
- if (!this.observers) {
515
- this.observers = [Listener];
516
- this.observerSlots = [Listener.sources.length - 1];
517
- } else {
518
- this.observers.push(Listener);
519
- this.observerSlots.push(Listener.sources.length - 1);
520
- }
531
+ if (!node.observers) {
532
+ node.observers = [to];
533
+ node.observerSlots = [to.sources.length - 1];
534
+ } else {
535
+ node.observers.push(to);
536
+ node.observerSlots.push(to.sources.length - 1);
521
537
  }
522
- if (Transition && Transition.running && Transition.sources.has(this)) return this.tValue;
523
- return this.value;
524
- }
525
- function writeSignal(node, value, isComp) {
526
- if (node.comparator) {
527
- if (Transition && Transition.running && Transition.sources.has(node)) {
528
- if (node.comparator(node.tValue, value)) return value;
529
- } else if (node.comparator(node.value, value)) return value;
538
+ }
539
+ function writeSignal(node, value) {
540
+ if (typeof value === "function") {
541
+ value = value(node.pending !== NOTPENDING ? node.pending : node.value);
530
542
  }
543
+ return writeSource(node, value);
544
+ }
545
+ function writeSource(node, value) {
546
+ if (node.comparator && node.comparator(node.value, value)) return value;
531
547
  if (Pending) {
532
548
  if (node.pending === NOTPENDING) Pending.push(node);
533
549
  node.pending = value;
534
550
  return value;
535
551
  }
536
- let TransitionRunning = false;
537
- if (Transition) {
538
- TransitionRunning = Transition.running;
539
- if (TransitionRunning || !isComp && Transition.sources.has(node)) {
540
- Transition.sources.add(node);
541
- node.tValue = value;
542
- }
543
- if (!TransitionRunning) node.value = value;
544
- } else node.value = value;
552
+ node.value = value;
545
553
  if (node.observers && node.observers.length) {
546
554
  runUpdates(() => {
547
- for (let i = 0; i < node.observers.length; i += 1) {
555
+ for (let i = 0; i < node.observers.length; i++) {
548
556
  const o = node.observers[i];
549
- if (TransitionRunning && Transition.disposed.has(o)) continue;
550
557
  if (o.pure) Updates.push(o);else Effects.push(o);
551
- if (o.observers && (TransitionRunning && !o.tState || !TransitionRunning && !o.state)) markUpstream(o);
552
- if (TransitionRunning) o.tState = STALE;else o.state = STALE;
558
+ if (o.observers && !o.state) markUpstream(o);
559
+ o.state = STALE;
553
560
  }
554
561
  if (Updates.length > 10e5) {
555
562
  Updates = [];
@@ -562,17 +569,21 @@ function writeSignal(node, value, isComp) {
562
569
  }
563
570
  function updateComputation(node) {
564
571
  if (!node.fn) return;
572
+ if (Transition && Transition.sources.has(node)) {
573
+ Transition.updated.add(node);
574
+ if (!Transition.running) {
575
+ return queueMicrotask(() => runUpdates(() => {
576
+ Transition.running = true;
577
+ updateComputation(node);
578
+ }, false));
579
+ }
580
+ }
565
581
  cleanNode(node);
566
582
  const owner = Owner,
567
583
  listener = Listener,
568
584
  time = ExecCount;
569
585
  Listener = Owner = node;
570
586
  runComputation(node, node.value, time);
571
- if (Transition && !Transition.running && Transition.sources.has(node)) {
572
- Transition.running = true;
573
- runComputation(node, node.tValue, time);
574
- Transition.running = false;
575
- }
576
587
  Listener = listener;
577
588
  Owner = owner;
578
589
  }
@@ -585,10 +596,7 @@ function runComputation(node, value, time) {
585
596
  }
586
597
  if (!node.updatedAt || node.updatedAt <= time) {
587
598
  if (node.observers && node.observers.length) {
588
- writeSignal(node, nextValue, true);
589
- } else if (Transition && Transition.running && node.pure) {
590
- Transition.sources.add(node);
591
- node.tValue = nextValue;
599
+ writeSource(node, nextValue);
592
600
  } else node.value = nextValue;
593
601
  node.updatedAt = time;
594
602
  }
@@ -597,7 +605,7 @@ function createComputation(fn, init, pure, state = STALE, options) {
597
605
  const c = {
598
606
  fn,
599
607
  state: state,
600
- updatedAt: null,
608
+ updatedAt: 0,
601
609
  owned: null,
602
610
  sources: null,
603
611
  sourceSlots: null,
@@ -607,41 +615,24 @@ function createComputation(fn, init, pure, state = STALE, options) {
607
615
  context: null,
608
616
  pure
609
617
  };
610
- if (Transition && Transition.running) {
611
- c.state = 0;
612
- c.tState = state;
613
- }
614
618
  if (Owner === null) ;else if (Owner !== UNOWNED) {
615
- if (Transition && Transition.running && Owner.pure) {
616
- if (!Owner.tOwned) Owner.tOwned = [c];else Owner.tOwned.push(c);
617
- } else {
618
- if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
619
- }
619
+ if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
620
620
  }
621
+ if (Transition && Transition.running) Transition.sources.add(c);
621
622
  return c;
622
623
  }
623
624
  function runTop(node) {
624
- const runningTransition = Transition && Transition.running;
625
- if (!runningTransition && node.state !== STALE) return node.state = 0;
626
- if (runningTransition && node.tState !== STALE) return node.tState = 0;
625
+ if (node.state !== STALE) return node.state = 0;
627
626
  if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node);
628
627
  const ancestors = [node];
629
628
  while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) {
630
- if (runningTransition && Transition.disposed.has(node)) return;
631
- if (node.state || runningTransition && node.tState) ancestors.push(node);
629
+ if (node.state) ancestors.push(node);
632
630
  }
633
631
  for (let i = ancestors.length - 1; i >= 0; i--) {
634
632
  node = ancestors[i];
635
- if (runningTransition) {
636
- let top = node,
637
- prev = ancestors[i + 1];
638
- while ((top = top.owner) && top !== prev) {
639
- if (Transition.disposed.has(top)) return;
640
- }
641
- }
642
- if (node.state === STALE || runningTransition && node.tState === STALE) {
633
+ if (node.state === STALE) {
643
634
  updateComputation(node);
644
- } else if (node.state === PENDING || runningTransition && node.tState === PENDING) {
635
+ } else if (node.state === PENDING) {
645
636
  const updates = Updates;
646
637
  Updates = null;
647
638
  lookDownstream(node);
@@ -678,24 +669,11 @@ function completeUpdates(wait) {
678
669
  setTransPending(true);
679
670
  return;
680
671
  }
681
- const sources = Transition.sources;
672
+ const t = Transition;
682
673
  cbs = Transition.cb;
683
- Effects.forEach(e => {
684
- e.state = STALE;
685
- delete e.tState;
686
- });
687
674
  Transition = null;
688
675
  batch(() => {
689
- sources.forEach(v => {
690
- v.value = v.tValue;
691
- if (v.owned) {
692
- for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]);
693
- }
694
- if (v.tOwned) v.owned = v.tOwned;
695
- delete v.tValue;
696
- delete v.tOwned;
697
- v.tState = 0;
698
- });
676
+ mergeTransition(t);
699
677
  setTransPending(false);
700
678
  });
701
679
  }
@@ -744,24 +722,75 @@ function runUserEffects(queue) {
744
722
  }
745
723
  function lookDownstream(node) {
746
724
  node.state = 0;
747
- for (let i = 0; i < node.sources.length; i += 1) {
725
+ for (let i = 0; i < node.sources.length; i++) {
748
726
  const source = node.sources[i];
749
727
  if (source.sources) {
750
- if (source.state === STALE || Transition && Transition.running && source.tState) runTop(source);else if (source.state === PENDING) lookDownstream(source);
728
+ if (source.state === STALE) runTop(source);else if (source.state === PENDING) lookDownstream(source);
751
729
  }
752
730
  }
753
731
  }
754
732
  function markUpstream(node) {
755
- const runningTransition = Transition && Transition.running;
756
- for (let i = 0; i < node.observers.length; i += 1) {
733
+ for (let i = 0; i < node.observers.length; i++) {
757
734
  const o = node.observers[i];
758
- if (!o.state || runningTransition && !o.tState) {
759
- if (runningTransition) o.tState = PENDING;else o.state = PENDING;
735
+ if (!o.state) {
736
+ o.state = PENDING;
760
737
  if (o.pure) Updates.push(o);else Effects.push(o);
761
738
  o.observers && markUpstream(o);
762
739
  }
763
740
  }
764
741
  }
742
+ function forkSource(s, p, slot) {
743
+ let fork;
744
+ if (!(fork = Transition.lookup.get(s) || Transition.sources.has(s) && s)) {
745
+ Transition.lookup.set(s, fork = { ...s
746
+ });
747
+ Transition.sources.add(fork);
748
+ if (fork.observers) {
749
+ fork.observers = [...new Set(fork.observers)];
750
+ fork.observerSlots = [];
751
+ fork.observers.forEach((o, i) => forkSource(o, fork, i));
752
+ }
753
+ if (fork.sources) {
754
+ fork.sources = [p];
755
+ fork.sourceSlots = [slot];
756
+ replaceObservers(fork, p, slot, 0);
757
+ }
758
+ fork.owned && (fork.owned = null);
759
+ fork.cleanups && (fork.cleanups = null);
760
+ } else if ("sources" in fork) {
761
+ fork.sources.push(p);
762
+ fork.sourceSlots.push(slot);
763
+ replaceObservers(fork, p, slot, fork.sources.length - 1);
764
+ }
765
+ return fork;
766
+ }
767
+ function replaceObservers(node, source, slot, sourceSlot) {
768
+ source.observers || (source.observers = []);
769
+ source.observerSlots || (source.observerSlots = []);
770
+ source.observers[slot] = node;
771
+ source.observerSlots[slot] = sourceSlot;
772
+ }
773
+ function mergeTransition(transition) {
774
+ const reverse = new Map(Array.from(transition.lookup, entry => [entry[1], entry[0]]));
775
+ transition.lookup.forEach((fork, og) => {
776
+ if ("sources" in fork && (fork.state || transition.updated.has(fork))) cleanNode(og);
777
+ });
778
+ transition.lookup.forEach((fork, og) => {
779
+ if ("sources" in fork && !fork.state && !transition.updated.has(fork)) return;
780
+ transition.updated.delete(fork);
781
+ Object.assign(og, fork);
782
+ if (og.sources) {
783
+ og.sourceSlots.forEach((slot, i) => {
784
+ og.sources[i] = reverse.get(og.sources[i]) || og.sources[i];
785
+ replaceObservers(og, og.sources[i], slot, i);
786
+ });
787
+ }
788
+ });
789
+ Effects.forEach((e, i) => {
790
+ const replace = reverse.get(e);
791
+ if (replace) Effects[i] = replace;
792
+ });
793
+ }
765
794
  function cleanNode(node) {
766
795
  let i;
767
796
  if (node.sources) {
@@ -780,13 +809,7 @@ function cleanNode(node) {
780
809
  }
781
810
  }
782
811
  }
783
- if (Transition && Transition.running && node.pure) {
784
- if (node.tOwned) {
785
- for (i = 0; i < node.tOwned.length; i++) cleanNode(node.tOwned[i]);
786
- delete node.tOwned;
787
- }
788
- reset(node, true);
789
- } else if (node.owned) {
812
+ if (node.owned) {
790
813
  for (i = 0; i < node.owned.length; i++) cleanNode(node.owned[i]);
791
814
  node.owned = null;
792
815
  }
@@ -794,18 +817,9 @@ function cleanNode(node) {
794
817
  for (i = 0; i < node.cleanups.length; i++) node.cleanups[i]();
795
818
  node.cleanups = null;
796
819
  }
797
- if (Transition && Transition.running) node.tState = 0;else node.state = 0;
820
+ node.state = 0;
798
821
  node.context = null;
799
822
  }
800
- function reset(node, top) {
801
- if (!top) {
802
- node.tState = 0;
803
- Transition.disposed.add(node);
804
- }
805
- if (node.owned) {
806
- for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]);
807
- }
808
- }
809
823
  function handleError(err) {
810
824
  const fns = ERROR && lookup(Owner, ERROR);
811
825
  if (!fns) throw err;