MCPcopy
hub / github.com/sveltejs/svelte / #commit

Method #commit

packages/svelte/src/internal/client/reactivity/batch.js:652–777  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

650 }
651
652 #commit() {
653 // If there are other pending batches, they now need to be 'rebased' —
654 // in other words, we re-run block/async effects with the newly
655 // committed state, unless the batch in question has a more
656 // recent value for a given source
657 for (let batch = first_batch; batch !== null; batch = batch.#next) {
658 var is_earlier = batch.id < this.id;
659
660 /** @type {Source[]} */
661 var sources = [];
662
663 for (const [source, [value, is_derived]] of this.current) {
664 if (batch.current.has(source)) {
665 var batch_value = /** @type {[any, boolean]} */ (batch.current.get(source))[0]; // faster than destructuring
666
667 if (is_earlier && value !== batch_value) {
668 // bring the value up to date
669 batch.current.set(source, [value, is_derived]);
670 } else {
671 // same value or later batch has more recent value,
672 // no need to re-run these effects
673 continue;
674 }
675 }
676
677 sources.push(source);
678 }
679
680 if (is_earlier) {
681 // TODO do we need to restart these in some cases, instead of
682 // immediately resolving them? Likely not because of how this.apply() works.
683 for (const [effect, deferred] of this.async_deriveds) {
684 const d = batch.async_deriveds.get(effect);
685 if (d) deferred.promise.then(d.resolve).catch(d.reject);
686 }
687 }
688
689 var current = [...batch.current.keys()].filter(
690 (source) => !(/** @type {[any, boolean]} */ (batch.current.get(source))[1])
691 );
692
693 // If not started yet or no sources to update (which is e.g. possible for the very first batch) then bail
694 if (!batch.#started || current.length === 0) continue;
695
696 // Re-run async/block effects that depend on distinct values changed in both batches (ignoring deriveds)
697 var others = current.filter((source) => !this.current.has(source));
698
699 if (others.length === 0) {
700 if (is_earlier) {
701 // this batch is now obsolete and can be discarded
702 batch.discard();
703 }
704 } else if (sources.length > 0) {
705 // The microtask queue can contain the batch already scheduled to run right
706 // after this one is finished, so throwing the invariant would be wrong here.
707 if (DEV && !batch.#decrement_queued) {
708 invariant(batch.#roots.length === 0, 'Batch has scheduled roots');
709 }

Callers 2

#processMethod · 0.95
ensureMethod · 0.80

Calls 15

invariantFunction · 0.90
set_signal_statusFunction · 0.90
mark_effectsFunction · 0.85
depends_onFunction · 0.85
pushMethod · 0.80
unskip_effectMethod · 0.80
scheduleMethod · 0.80
#defer_effectsMethod · 0.80
activateMethod · 0.80
#traverseMethod · 0.80
deactivateMethod · 0.80
setMethod · 0.65

Tested by

no test coverage detected