pull/16197/head
Rich Harris 4 months ago
parent 7e83cdae23
commit 2071160ce8

@ -86,18 +86,61 @@ export class Batch {
}
if (this.async_effects.length === 0 && this.settled()) {
var render_effects = this.render_effects;
var effects = this.effects;
var merged = false;
// if there are older batches with overlapping
// state, we can't commit this batch. instead,
// we merge it into the older batches
for (const batch of batches) {
if (batch === this) break;
for (const [source] of batch.#current) {
if (this.#current.has(source)) {
merged = true;
for (const [source, value] of this.#current) {
batch.#current.set(source, value);
// TODO what about batch.#previous?
}
for (const e of this.render_effects) {
set_signal_status(e, CLEAN);
// TODO use sets instead of arrays
if (!batch.render_effects.includes(e)) {
batch.render_effects.push(e);
}
}
for (const e of this.effects) {
set_signal_status(e, CLEAN);
// TODO use sets instead of arrays
if (!batch.effects.includes(e)) {
batch.effects.push(e);
}
}
this.remove();
break;
}
}
}
this.render_effects = [];
this.effects = [];
if (merged) {
this.remove();
} else {
var render_effects = this.render_effects;
var effects = this.effects;
this.commit();
this.render_effects = [];
this.effects = [];
this.commit();
flush_queued_effects(render_effects);
flush_queued_effects(effects);
flush_queued_effects(render_effects);
flush_queued_effects(effects);
this.deferred?.resolve();
this.deferred?.resolve();
}
} else {
for (const e of this.render_effects) set_signal_status(e, CLEAN);
for (const e of this.effects) set_signal_status(e, CLEAN);
@ -133,24 +176,24 @@ export class Batch {
remove() {
batches.delete(this);
for (var batch of batches) {
/** @type {Source} */
var source;
if (batch.#id < this.#id) {
// other batch is older than this
for (source of this.#previous.keys()) {
batch.#previous.delete(source);
}
} else {
// other batch is newer than this
for (source of batch.#previous.keys()) {
if (this.#previous.has(source)) {
batch.#previous.set(source, source.v);
}
}
}
}
// for (var batch of batches) {
// /** @type {Source} */
// var source;
// if (batch.#id < this.#id) {
// // other batch is older than this
// for (source of this.#previous.keys()) {
// batch.#previous.delete(source);
// }
// } else {
// // other batch is newer than this
// for (source of batch.#previous.keys()) {
// if (this.#previous.has(source)) {
// batch.#previous.set(source, source.v);
// }
// }
// }
// }
}
restore() {

@ -0,0 +1,40 @@
import { flushSync, settled, tick } from 'svelte';
import { test } from '../../test';
export default test({
html: `<button>both</button><button>a</button><button>b</button><p>loading...</p>`,
async test({ assert, target }) {
const [both, a, b] = target.querySelectorAll('button');
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
assert.htmlEqual(
target.innerHTML,
`
<button>both</button><button>a</button><button>b</button>
<p>1 * 2 = 2</p>
<p>2 * 2 = 4</p>
`
);
flushSync(() => both.click());
flushSync(() => b.click());
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
assert.htmlEqual(
target.innerHTML,
`
<button>both</button><button>a</button><button>b</button>
<p>2 * 2 = 4</p>
<p>4 * 2 = 8</p>
`
);
}
});

@ -0,0 +1,17 @@
<script>
let a = $state(1);
let b = $state(2);
</script>
<button onclick={() => {a += 1; b += 1;}}>both</button>
<button onclick={() => {a += 1;}}>a</button>
<button onclick={() => {b += 1;}}>b</button>
<svelte:boundary>
<p>{a} * 2 = {await (a * 2)}</p>
<p>{b} * 2 = {b * 2}</p>
{#snippet pending()}
<p>loading...</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save