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/dev.js CHANGED
@@ -141,7 +141,6 @@ const UNOWNED = {
141
141
  context: null,
142
142
  owner: null
143
143
  };
144
- const [transPending, setTransPending] = /*@__PURE__*/createSignal(false);
145
144
  var Owner = null;
146
145
  let Transition = null;
147
146
  let Scheduler = null;
@@ -151,6 +150,7 @@ let Updates = null;
151
150
  let Effects = null;
152
151
  let ExecCount = 0;
153
152
  let rootCount = 0;
153
+ const [transPending, setTransPending] = /*@__PURE__*/createSignal(false);
154
154
  function createRoot(fn, detachedOwner) {
155
155
  detachedOwner && (Owner = detachedOwner);
156
156
  const listener = Listener,
@@ -182,12 +182,24 @@ function createSignal(value, options) {
182
182
  pending: NOTPENDING,
183
183
  comparator: options.equals || undefined
184
184
  };
185
+ if (Transition && Transition.running) Transition.sources.add(s);
185
186
  if (!options.internal) s.name = registerGraph(options.name || hashValue(value), s);
186
- return [readSignal.bind(s), value => {
187
- if (typeof value === "function") {
188
- 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
+ return [() => {
188
+ let sig = s;
189
+ Transition && Transition.running && (sig = Transition.lookup.get(s) || sig);
190
+ if (Listener !== null) logRead(sig, Listener);
191
+ return sig.value;
192
+ }, value => {
193
+ let sig = s;
194
+ if (Transition) {
195
+ if (Transition.running && !(sig = Transition.lookup.get(s))) {
196
+ sig = forkSource(s);
197
+ } else if (!Transition.running) {
198
+ const other = Transition.lookup.get(s);
199
+ if (other) writeSignal(other, value);
200
+ }
189
201
  }
190
- return writeSignal(s, value);
202
+ return writeSignal(sig, value);
191
203
  }];
192
204
  }
193
205
  function createComputed(fn, value, options) {
@@ -212,9 +224,20 @@ function createMemo(fn, value, options) {
212
224
  c.observerSlots = null;
213
225
  c.comparator = options.equals || undefined;
214
226
  updateComputation(c);
215
- return readSignal.bind(c);
227
+ return () => {
228
+ let sig = c;
229
+ Transition && Transition.running && (sig = Transition.lookup.get(c) || sig);
230
+ if (c.state && c.sources) {
231
+ const updates = Updates;
232
+ Updates = null;
233
+ c.state === STALE ? updateComputation(c) : lookDownstream(c);
234
+ Updates = updates;
235
+ }
236
+ if (Listener !== null) logRead(sig, Listener);
237
+ return sig.value;
238
+ };
216
239
  }
217
- function createResource(source, fetcher, options = {}) {
240
+ function createResource(source, fetcher, options) {
218
241
  if (arguments.length === 2) {
219
242
  if (typeof fetcher === "object") {
220
243
  options = fetcher;
@@ -226,7 +249,7 @@ function createResource(source, fetcher, options = {}) {
226
249
  source = true;
227
250
  }
228
251
  const contexts = new Set(),
229
- [s, set] = createSignal(options.initialValue),
252
+ [s, set] = createSignal(options?.initialValue),
230
253
  [track, trigger] = createSignal(undefined, {
231
254
  equals: false
232
255
  }),
@@ -347,8 +370,9 @@ function createDeferred(source, options) {
347
370
  }
348
371
  function createSelector(source, fn = equalFn, options) {
349
372
  const subs = new Map();
373
+ let current;
350
374
  const node = createComputation(p => {
351
- const v = source();
375
+ const v = current = source();
352
376
  for (const key of subs.keys()) if (fn(key, v) || p !== undefined && fn(key, p)) {
353
377
  const l = subs.get(key);
354
378
  for (const c of l.values()) {
@@ -364,11 +388,9 @@ function createSelector(source, fn = equalFn, options) {
364
388
  if (listener = Listener) {
365
389
  let l;
366
390
  if (l = subs.get(key)) l.add(listener);else subs.set(key, l = new Set([listener]));
367
- onCleanup(() => {
368
- l.size > 1 ? l.delete(listener) : subs.delete(key);
369
- });
391
+ onCleanup(() => l.size > 1 ? l.delete(listener) : subs.delete(key));
370
392
  }
371
- return fn(key, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value);
393
+ return fn(key, current);
372
394
  };
373
395
  }
374
396
  function batch(fn) {
@@ -381,12 +403,12 @@ function batch(fn) {
381
403
  Pending = null;
382
404
  }
383
405
  runUpdates(() => {
384
- for (let i = 0; i < q.length; i += 1) {
406
+ for (let i = 0; i < q.length; i++) {
385
407
  const data = q[i];
386
408
  if (data.pending !== NOTPENDING) {
387
409
  const pending = data.pending;
388
410
  data.pending = NOTPENDING;
389
- writeSignal(data, pending);
411
+ writeSource(data, pending);
390
412
  }
391
413
  }
392
414
  }, false);
@@ -451,27 +473,29 @@ function enableScheduling(scheduler = requestCallback) {
451
473
  Scheduler = scheduler;
452
474
  }
453
475
  function startTransition(fn, cb) {
454
- if (Scheduler || SuspenseContext) {
455
- Transition || (Transition = {
456
- sources: new Set(),
457
- effects: [],
458
- promises: new Set(),
459
- disposed: new Set(),
460
- queue: new Set(),
461
- running: true,
462
- cb: []
463
- });
464
- cb && Transition.cb.push(cb);
465
- Transition.running = true;
466
- }
467
- batch(fn);
468
- if (!Scheduler && !SuspenseContext && cb) cb();
476
+ queueMicrotask(() => {
477
+ if (Scheduler || SuspenseContext) {
478
+ Transition || (Transition = {
479
+ sources: new Set(),
480
+ lookup: new Map(),
481
+ updated: new Set(),
482
+ effects: [],
483
+ promises: new Set(),
484
+ queue: new Set(),
485
+ running: true,
486
+ cb: []
487
+ });
488
+ cb && Transition.cb.push(cb);
489
+ Transition.running = true;
490
+ }
491
+ batch(fn);
492
+ if (!Scheduler && !SuspenseContext && cb) cb();
493
+ });
469
494
  }
470
495
  function useTransition() {
471
496
  return [transPending, startTransition];
472
497
  }
473
498
  function resumeEffects(e) {
474
- Transition && (Transition.running = true);
475
499
  Effects.push.apply(Effects, e);
476
500
  e.length = 0;
477
501
  }
@@ -483,7 +507,7 @@ function devComponent(Comp, props) {
483
507
  c.state = 0;
484
508
  c.componentName = Comp.name;
485
509
  updateComputation(c);
486
- return c.tValue !== undefined ? c.tValue : c.value;
510
+ return c.value;
487
511
  }
488
512
  function hashValue(v) {
489
513
  const s = new Set();
@@ -491,6 +515,14 @@ function hashValue(v) {
491
515
  if (typeof v === "object" && v != null) {
492
516
  if (s.has(v)) return;
493
517
  s.add(v);
518
+ const keys = Object.keys(v);
519
+ const desc = Object.getOwnPropertyDescriptors(v);
520
+ const newDesc = keys.reduce((memo, key) => {
521
+ const value = desc[key];
522
+ if (!value.get) memo[key] = value;
523
+ return memo;
524
+ }, {});
525
+ v = Object.create({}, newDesc);
494
526
  }
495
527
  if (typeof v === "bigint") {
496
528
  return `${v.toString()}n`;
@@ -534,61 +566,44 @@ let SuspenseContext;
534
566
  function getSuspenseContext() {
535
567
  return SuspenseContext || (SuspenseContext = createContext({}));
536
568
  }
537
- function readSignal() {
538
- if (this.state && this.sources) {
539
- const updates = Updates;
540
- Updates = null;
541
- this.state === STALE || Transition && Transition.running && this.tState ? updateComputation(this) : lookDownstream(this);
542
- Updates = updates;
569
+ function logRead(node, to) {
570
+ const sSlot = node.observers ? node.observers.length : 0;
571
+ if (!to.sources) {
572
+ to.sources = [node];
573
+ to.sourceSlots = [sSlot];
574
+ } else {
575
+ to.sources.push(node);
576
+ to.sourceSlots.push(sSlot);
543
577
  }
544
- if (Listener) {
545
- const sSlot = this.observers ? this.observers.length : 0;
546
- if (!Listener.sources) {
547
- Listener.sources = [this];
548
- Listener.sourceSlots = [sSlot];
549
- } else {
550
- Listener.sources.push(this);
551
- Listener.sourceSlots.push(sSlot);
552
- }
553
- if (!this.observers) {
554
- this.observers = [Listener];
555
- this.observerSlots = [Listener.sources.length - 1];
556
- } else {
557
- this.observers.push(Listener);
558
- this.observerSlots.push(Listener.sources.length - 1);
559
- }
578
+ if (!node.observers) {
579
+ node.observers = [to];
580
+ node.observerSlots = [to.sources.length - 1];
581
+ } else {
582
+ node.observers.push(to);
583
+ node.observerSlots.push(to.sources.length - 1);
560
584
  }
561
- if (Transition && Transition.running && Transition.sources.has(this)) return this.tValue;
562
- return this.value;
563
- }
564
- function writeSignal(node, value, isComp) {
565
- if (node.comparator) {
566
- if (Transition && Transition.running && Transition.sources.has(node)) {
567
- if (node.comparator(node.tValue, value)) return value;
568
- } else if (node.comparator(node.value, value)) return value;
585
+ }
586
+ function writeSignal(node, value) {
587
+ if (typeof value === "function") {
588
+ value = value(node.pending !== NOTPENDING ? node.pending : node.value);
569
589
  }
590
+ return writeSource(node, value);
591
+ }
592
+ function writeSource(node, value) {
593
+ if (node.comparator && node.comparator(node.value, value)) return value;
570
594
  if (Pending) {
571
595
  if (node.pending === NOTPENDING) Pending.push(node);
572
596
  node.pending = value;
573
597
  return value;
574
598
  }
575
- let TransitionRunning = false;
576
- if (Transition) {
577
- TransitionRunning = Transition.running;
578
- if (TransitionRunning || !isComp && Transition.sources.has(node)) {
579
- Transition.sources.add(node);
580
- node.tValue = value;
581
- }
582
- if (!TransitionRunning) node.value = value;
583
- } else node.value = value;
599
+ node.value = value;
584
600
  if (node.observers && node.observers.length) {
585
601
  runUpdates(() => {
586
- for (let i = 0; i < node.observers.length; i += 1) {
602
+ for (let i = 0; i < node.observers.length; i++) {
587
603
  const o = node.observers[i];
588
- if (TransitionRunning && Transition.disposed.has(o)) continue;
589
604
  if (o.pure) Updates.push(o);else Effects.push(o);
590
- if (o.observers && (TransitionRunning && !o.tState || !TransitionRunning && !o.state)) markUpstream(o);
591
- if (TransitionRunning) o.tState = STALE;else o.state = STALE;
605
+ if (o.observers && !o.state) markUpstream(o);
606
+ o.state = STALE;
592
607
  }
593
608
  if (Updates.length > 10e5) {
594
609
  Updates = [];
@@ -601,17 +616,21 @@ function writeSignal(node, value, isComp) {
601
616
  }
602
617
  function updateComputation(node) {
603
618
  if (!node.fn) return;
619
+ if (Transition && Transition.sources.has(node)) {
620
+ Transition.updated.add(node);
621
+ if (!Transition.running) {
622
+ return queueMicrotask(() => runUpdates(() => {
623
+ Transition.running = true;
624
+ updateComputation(node);
625
+ }, false));
626
+ }
627
+ }
604
628
  cleanNode(node);
605
629
  const owner = Owner,
606
630
  listener = Listener,
607
631
  time = ExecCount;
608
632
  Listener = Owner = node;
609
633
  runComputation(node, node.value, time);
610
- if (Transition && !Transition.running && Transition.sources.has(node)) {
611
- Transition.running = true;
612
- runComputation(node, node.tValue, time);
613
- Transition.running = false;
614
- }
615
634
  Listener = listener;
616
635
  Owner = owner;
617
636
  }
@@ -624,10 +643,7 @@ function runComputation(node, value, time) {
624
643
  }
625
644
  if (!node.updatedAt || node.updatedAt <= time) {
626
645
  if (node.observers && node.observers.length) {
627
- writeSignal(node, nextValue, true);
628
- } else if (Transition && Transition.running && node.pure) {
629
- Transition.sources.add(node);
630
- node.tValue = nextValue;
646
+ writeSource(node, nextValue);
631
647
  } else node.value = nextValue;
632
648
  node.updatedAt = time;
633
649
  }
@@ -636,7 +652,7 @@ function createComputation(fn, init, pure, state = STALE, options) {
636
652
  const c = {
637
653
  fn,
638
654
  state: state,
639
- updatedAt: null,
655
+ updatedAt: 0,
640
656
  owned: null,
641
657
  sources: null,
642
658
  sourceSlots: null,
@@ -646,42 +662,25 @@ function createComputation(fn, init, pure, state = STALE, options) {
646
662
  context: null,
647
663
  pure
648
664
  };
649
- if (Transition && Transition.running) {
650
- c.state = 0;
651
- c.tState = state;
652
- }
653
665
  if (Owner === null) console.warn("computations created outside a `createRoot` or `render` will never be disposed");else if (Owner !== UNOWNED) {
654
- if (Transition && Transition.running && Owner.pure) {
655
- if (!Owner.tOwned) Owner.tOwned = [c];else Owner.tOwned.push(c);
656
- } else {
657
- if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
658
- }
659
- c.name = options && options.name || `${Owner.name || "c"}-${(Owner.owned || Owner.tOwned).length}`;
666
+ if (!Owner.owned) Owner.owned = [c];else Owner.owned.push(c);
667
+ c.name = options && options.name || `${Owner.name || "c"}-${Owner.owned.length}`;
660
668
  }
669
+ if (Transition && Transition.running) Transition.sources.add(c);
661
670
  return c;
662
671
  }
663
672
  function runTop(node) {
664
- const runningTransition = Transition && Transition.running;
665
- if (!runningTransition && node.state !== STALE) return node.state = 0;
666
- if (runningTransition && node.tState !== STALE) return node.tState = 0;
673
+ if (node.state !== STALE) return node.state = 0;
667
674
  if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node);
668
675
  const ancestors = [node];
669
676
  while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) {
670
- if (runningTransition && Transition.disposed.has(node)) return;
671
- if (node.state || runningTransition && node.tState) ancestors.push(node);
677
+ if (node.state) ancestors.push(node);
672
678
  }
673
679
  for (let i = ancestors.length - 1; i >= 0; i--) {
674
680
  node = ancestors[i];
675
- if (runningTransition) {
676
- let top = node,
677
- prev = ancestors[i + 1];
678
- while ((top = top.owner) && top !== prev) {
679
- if (Transition.disposed.has(top)) return;
680
- }
681
- }
682
- if (node.state === STALE || runningTransition && node.tState === STALE) {
681
+ if (node.state === STALE) {
683
682
  updateComputation(node);
684
- } else if (node.state === PENDING || runningTransition && node.tState === PENDING) {
683
+ } else if (node.state === PENDING) {
685
684
  const updates = Updates;
686
685
  Updates = null;
687
686
  lookDownstream(node);
@@ -718,24 +717,11 @@ function completeUpdates(wait) {
718
717
  setTransPending(true);
719
718
  return;
720
719
  }
721
- const sources = Transition.sources;
720
+ const t = Transition;
722
721
  cbs = Transition.cb;
723
- Effects.forEach(e => {
724
- e.state = STALE;
725
- delete e.tState;
726
- });
727
722
  Transition = null;
728
723
  batch(() => {
729
- sources.forEach(v => {
730
- v.value = v.tValue;
731
- if (v.owned) {
732
- for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]);
733
- }
734
- if (v.tOwned) v.owned = v.tOwned;
735
- delete v.tValue;
736
- delete v.tOwned;
737
- v.tState = 0;
738
- });
724
+ mergeTransition(t);
739
725
  setTransPending(false);
740
726
  });
741
727
  }
@@ -785,24 +771,75 @@ function runUserEffects(queue) {
785
771
  }
786
772
  function lookDownstream(node) {
787
773
  node.state = 0;
788
- for (let i = 0; i < node.sources.length; i += 1) {
774
+ for (let i = 0; i < node.sources.length; i++) {
789
775
  const source = node.sources[i];
790
776
  if (source.sources) {
791
- if (source.state === STALE || Transition && Transition.running && source.tState) runTop(source);else if (source.state === PENDING) lookDownstream(source);
777
+ if (source.state === STALE) runTop(source);else if (source.state === PENDING) lookDownstream(source);
792
778
  }
793
779
  }
794
780
  }
795
781
  function markUpstream(node) {
796
- const runningTransition = Transition && Transition.running;
797
- for (let i = 0; i < node.observers.length; i += 1) {
782
+ for (let i = 0; i < node.observers.length; i++) {
798
783
  const o = node.observers[i];
799
- if (!o.state || runningTransition && !o.tState) {
800
- if (runningTransition) o.tState = PENDING;else o.state = PENDING;
784
+ if (!o.state) {
785
+ o.state = PENDING;
801
786
  if (o.pure) Updates.push(o);else Effects.push(o);
802
787
  o.observers && markUpstream(o);
803
788
  }
804
789
  }
805
790
  }
791
+ function forkSource(s, p, slot) {
792
+ let fork;
793
+ if (!(fork = Transition.lookup.get(s) || Transition.sources.has(s) && s)) {
794
+ Transition.lookup.set(s, fork = { ...s
795
+ });
796
+ Transition.sources.add(fork);
797
+ if (fork.observers) {
798
+ fork.observers = [...new Set(fork.observers)];
799
+ fork.observerSlots = [];
800
+ fork.observers.forEach((o, i) => forkSource(o, fork, i));
801
+ }
802
+ if (fork.sources) {
803
+ fork.sources = [p];
804
+ fork.sourceSlots = [slot];
805
+ replaceObservers(fork, p, slot, 0);
806
+ }
807
+ fork.owned && (fork.owned = null);
808
+ fork.cleanups && (fork.cleanups = null);
809
+ } else if ("sources" in fork) {
810
+ fork.sources.push(p);
811
+ fork.sourceSlots.push(slot);
812
+ replaceObservers(fork, p, slot, fork.sources.length - 1);
813
+ }
814
+ return fork;
815
+ }
816
+ function replaceObservers(node, source, slot, sourceSlot) {
817
+ source.observers || (source.observers = []);
818
+ source.observerSlots || (source.observerSlots = []);
819
+ source.observers[slot] = node;
820
+ source.observerSlots[slot] = sourceSlot;
821
+ }
822
+ function mergeTransition(transition) {
823
+ const reverse = new Map(Array.from(transition.lookup, entry => [entry[1], entry[0]]));
824
+ transition.lookup.forEach((fork, og) => {
825
+ if ("sources" in fork && (fork.state || transition.updated.has(fork))) cleanNode(og);
826
+ });
827
+ transition.lookup.forEach((fork, og) => {
828
+ if ("sources" in fork && !fork.state && !transition.updated.has(fork)) return;
829
+ transition.updated.delete(fork);
830
+ Object.assign(og, fork);
831
+ if (og.sources) {
832
+ og.sourceSlots.forEach((slot, i) => {
833
+ og.sources[i] = reverse.get(og.sources[i]) || og.sources[i];
834
+ replaceObservers(og, og.sources[i], slot, i);
835
+ });
836
+ }
837
+ });
838
+ Effects.forEach((e, i) => {
839
+ const replace = reverse.get(e);
840
+ if (replace) Effects[i] = replace;
841
+ });
842
+ }
806
843
  function cleanNode(node) {
807
844
  let i;
808
845
  if (node.sources) {
@@ -821,13 +858,7 @@ function cleanNode(node) {
821
858
  }
822
859
  }
823
860
  }
824
- if (Transition && Transition.running && node.pure) {
825
- if (node.tOwned) {
826
- for (i = 0; i < node.tOwned.length; i++) cleanNode(node.tOwned[i]);
827
- delete node.tOwned;
828
- }
829
- reset(node, true);
830
- } else if (node.owned) {
861
+ if (node.owned) {
831
862
  for (i = 0; i < node.owned.length; i++) cleanNode(node.owned[i]);
832
863
  node.owned = null;
833
864
  }
@@ -835,18 +866,9 @@ function cleanNode(node) {
835
866
  for (i = 0; i < node.cleanups.length; i++) node.cleanups[i]();
836
867
  node.cleanups = null;
837
868
  }
838
- if (Transition && Transition.running) node.tState = 0;else node.state = 0;
869
+ node.state = 0;
839
870
  node.context = null;
840
871
  }
841
- function reset(node, top) {
842
- if (!top) {
843
- node.tState = 0;
844
- Transition.disposed.add(node);
845
- }
846
- if (node.owned) {
847
- for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]);
848
- }
849
- }
850
872
  function handleError(err) {
851
873
  const fns = ERROR && lookup(Owner, ERROR);
852
874
  if (!fns) throw err;