mirror of https://github.com/sveltejs/svelte
commit
54cd91f055
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: keep batches alive until all async work is complete
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: don't preserve reactivity context across function boundaries
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: ensure guards (eg. if, each, key) run before their contents
|
||||
@ -0,0 +1,63 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [increment, shift] = target.querySelectorAll('button');
|
||||
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>0</button>
|
||||
<button>shift</button>
|
||||
<p>even</p>
|
||||
<p>0</p>
|
||||
`
|
||||
);
|
||||
|
||||
increment.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>1</button>
|
||||
<button>shift</button>
|
||||
<p>even</p>
|
||||
<p>0</p>
|
||||
`
|
||||
);
|
||||
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>1</button>
|
||||
<button>shift</button>
|
||||
<p>odd</p>
|
||||
<p>loading...</p>
|
||||
`
|
||||
);
|
||||
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>1</button>
|
||||
<button>shift</button>
|
||||
<p>odd</p>
|
||||
<p>1</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,36 @@
|
||||
<script>
|
||||
let resolvers = [];
|
||||
|
||||
function push(value) {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
resolvers.push(() => resolve(value));
|
||||
return promise;
|
||||
}
|
||||
|
||||
let count = $state(0);
|
||||
</script>
|
||||
|
||||
<button onclick={() => count += 1}>{$state.eager(count)}</button>
|
||||
<button onclick={() => resolvers.shift()?.()}>shift</button>
|
||||
|
||||
<svelte:boundary>
|
||||
{#if await push(count) % 2 === 0}
|
||||
<p>even</p>
|
||||
{:else}
|
||||
<p>odd</p>
|
||||
{/if}
|
||||
|
||||
{#key count}
|
||||
<svelte:boundary>
|
||||
<p>{await push(count)}</p>
|
||||
|
||||
{#snippet pending()}
|
||||
<p>loading...</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
{/key}
|
||||
|
||||
{#snippet pending()}
|
||||
<p>loading...</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
@ -1,7 +1,11 @@
|
||||
<script>
|
||||
$effect(() => {
|
||||
console.log('before');
|
||||
});
|
||||
|
||||
await 1;
|
||||
|
||||
$effect(() => {
|
||||
console.log('hello');
|
||||
console.log('after');
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { test } from '../../test';
|
||||
import { flushSync } from 'svelte';
|
||||
|
||||
export default test({
|
||||
mode: ['client'],
|
||||
async test({ target, assert, logs }) {
|
||||
const button = target.querySelector('button');
|
||||
|
||||
button?.click();
|
||||
flushSync();
|
||||
button?.click();
|
||||
flushSync();
|
||||
button?.click();
|
||||
flushSync();
|
||||
button?.click();
|
||||
flushSync();
|
||||
|
||||
assert.deepEqual(logs, ['two', 'one', 'two', 'one', 'two']);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
let b = $state(false);
|
||||
let v = $state("two");
|
||||
|
||||
$effect(() => {
|
||||
v = b ? "one" : "two";
|
||||
})
|
||||
</script>
|
||||
|
||||
<button onclick={() => b = !b}>Trigger</button>
|
||||
|
||||
{#if v === "one"}
|
||||
<div>if1 matched! {console.log('one')}</div>
|
||||
{:else if v === "two"}
|
||||
<div>if2 matched! {console.log('two')}</div>
|
||||
{:else}
|
||||
<div>nothing matched {console.log('else')}</div>
|
||||
{/if}
|
||||
@ -0,0 +1,13 @@
|
||||
import { test } from '../../test';
|
||||
import { flushSync } from 'svelte';
|
||||
|
||||
export default test({
|
||||
mode: ['client'],
|
||||
async test({ target, assert }) {
|
||||
const button = target.querySelector('button');
|
||||
|
||||
flushSync(() => button?.click());
|
||||
|
||||
assert.equal(target.textContent?.trim(), 'Trigger');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
let centerRow = $state({ nested: { optional: 2, required: 3 } });
|
||||
|
||||
let someChange = $state(false);
|
||||
$effect(() => {
|
||||
if (someChange) centerRow = undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if centerRow?.nested}
|
||||
{#if centerRow?.nested?.optional != undefined && centerRow.nested.optional > 0}
|
||||
op: {centerRow.nested.optional}<br />
|
||||
{:else}
|
||||
req: {centerRow.nested.required}<br />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<button onclick={() => (someChange = true)}>Trigger</button>
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
let { p } = $props();
|
||||
$effect.pre(() => {
|
||||
console.log('running ' + p)
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,13 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
mode: ['client'],
|
||||
async test({ assert, target, logs }) {
|
||||
const button = target.querySelector('button');
|
||||
|
||||
button?.click();
|
||||
flushSync();
|
||||
assert.deepEqual(logs, ['pre', 'running b', 'pre', 'pre']);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
import Component from './Component.svelte';
|
||||
|
||||
let p = $state('b');
|
||||
|
||||
$effect.pre(() => {
|
||||
console.log('pre')
|
||||
if (p === 'a') p = null;
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if p || !p}
|
||||
{#if p}
|
||||
<Component {p} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<button onclick={() => p = 'a'}>a</button>
|
||||
@ -0,0 +1,3 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({ compileOptions: { experimental: { async: true } } });
|
||||
@ -0,0 +1,52 @@
|
||||
import 'svelte/internal/disclose-version';
|
||||
import 'svelte/internal/flags/async';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
export default function Async_in_derived($$anchor, $$props) {
|
||||
$.push($$props, true);
|
||||
|
||||
$.async_body($$anchor, async ($$anchor) => {
|
||||
let yes1 = (await $.save($.async_derived(async () => (await $.save(1))())))();
|
||||
let yes2 = (await $.save($.async_derived(async () => foo((await $.save(1))()))))();
|
||||
|
||||
let no1 = $.derived(async () => {
|
||||
return await 1;
|
||||
});
|
||||
|
||||
let no2 = $.derived(() => async () => {
|
||||
return await 1;
|
||||
});
|
||||
|
||||
if ($.aborted()) return;
|
||||
|
||||
var fragment = $.comment();
|
||||
var node = $.first_child(fragment);
|
||||
|
||||
{
|
||||
var consequent = ($$anchor) => {
|
||||
$.async_body($$anchor, async ($$anchor) => {
|
||||
const yes1 = (await $.save($.async_derived(async () => (await $.save(1))())))();
|
||||
const yes2 = (await $.save($.async_derived(async () => foo((await $.save(1))()))))();
|
||||
|
||||
const no1 = $.derived(() => (async () => {
|
||||
return await 1;
|
||||
})());
|
||||
|
||||
const no2 = $.derived(() => (async () => {
|
||||
return await 1;
|
||||
})());
|
||||
|
||||
if ($.aborted()) return;
|
||||
});
|
||||
};
|
||||
|
||||
$.if(node, ($$render) => {
|
||||
if (true) $$render(consequent);
|
||||
});
|
||||
}
|
||||
|
||||
$.append($$anchor, fragment);
|
||||
});
|
||||
|
||||
$.pop();
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import 'svelte/internal/flags/async';
|
||||
import * as $ from 'svelte/internal/server';
|
||||
|
||||
export default function Async_in_derived($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer) => {
|
||||
$$renderer.async(async ($$renderer) => {
|
||||
let yes1 = (await $.save(1))();
|
||||
let yes2 = foo((await $.save(1))());
|
||||
|
||||
let no1 = (async () => {
|
||||
return await 1;
|
||||
})();
|
||||
|
||||
let no2 = async () => {
|
||||
return await 1;
|
||||
};
|
||||
|
||||
$$renderer.async(async ($$renderer) => {
|
||||
if (true) {
|
||||
$$renderer.push('<!--[-->');
|
||||
|
||||
const yes1 = (await $.save(1))();
|
||||
const yes2 = foo((await $.save(1))());
|
||||
|
||||
const no1 = (async () => {
|
||||
return await 1;
|
||||
})();
|
||||
|
||||
const no2 = (async () => {
|
||||
return await 1;
|
||||
})();
|
||||
} else {
|
||||
$$renderer.push('<!--[!-->');
|
||||
}
|
||||
});
|
||||
|
||||
$$renderer.push(`<!--]-->`);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
<script>
|
||||
let yes1 = $derived(await 1);
|
||||
let yes2 = $derived(foo(await 1));
|
||||
let no1 = $derived.by(async () => {
|
||||
return await 1;
|
||||
});
|
||||
let no2 = $derived(async () => {
|
||||
return await 1;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if true}
|
||||
{@const yes1 = await 1}
|
||||
{@const yes2 = foo(await 1)}
|
||||
{@const no1 = (async () => {
|
||||
return await 1;
|
||||
})()}
|
||||
{@const no2 = (async () => {
|
||||
return await 1;
|
||||
})()}
|
||||
{/if}
|
||||
Loading…
Reference in new issue