Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eight-news-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure fork always accesses correct values
13 changes: 9 additions & 4 deletions packages/svelte/src/internal/client/reactivity/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
DERIVED,
BOUNDARY_EFFECT,
EAGER_EFFECT,
HEAD_EFFECT
HEAD_EFFECT,
ERROR_VALUE
} from '#client/constants';
import { async_mode_flag } from '../../flags/index.js';
import { deferred, define_property } from '../../shared/utils.js';
Expand Down Expand Up @@ -285,12 +286,16 @@ export class Batch {
this.previous.set(source, value);
}

this.current.set(source, source.v);
batch_values?.set(source, source.v);
// Don't save this as it would mean it's not thrown in the `runtime.js#get` function
if ((source.f & ERROR_VALUE) === 0) {
this.current.set(source, source.v);
batch_values?.set(source, source.v);
}
}

activate() {
current_batch = this;
this.apply();
}

deactivate() {
Expand Down Expand Up @@ -492,7 +497,7 @@ export class Batch {
}

apply() {
if (!async_mode_flag || batches.size === 1) return;
if (!async_mode_flag || (!this.is_fork && batches.size === 1)) return;

// if there are multiple batches, we are 'time travelling' —
// we need to override values with the ones in this batch...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
let { x } = $props();
console.log(x);
await Promise.resolve();
console.log(x);
</script>

{x}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { test } from '../../test';

export default test({
async test({ assert, target, logs }) {
const btn = target.querySelector('button');

btn?.click();
await new Promise((r) => setTimeout(r, 2));
assert.htmlEqual(target.innerHTML, `<button>fork</button> universe`);
assert.deepEqual(logs, ['universe', 'universe']);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script>
import { fork } from 'svelte';
import Child from './Child.svelte';
let x = $state('world');
</script>

<button onclick={async () => {
const f = fork(() => {
x = 'universe'
});
await new Promise(r => setTimeout(r));
f.commit();
}}>fork</button>

{#if x === 'universe'}
<Child {x} />
{/if}
Loading