Skip to content

Commit 9d74e22

Browse files
committed
run bindings in derived
1 parent d4417cb commit 9d74e22

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

packages/svelte/src/compiler/phases/3-transform/shared/spread_bindings.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@ export function init_spread_bindings(spread_expression, { state, visit }) {
1616
? b.literal(source.slice(spread_expression.start, spread_expression.end))
1717
: undefined;
1818

19-
const id = state.scope.generate('$$spread_binding');
20-
const get = b.id(id + '_get');
21-
const set = b.id(id + '_set');
19+
const id = b.id(state.scope.generate('$$spread_binding'));
2220
state.init.push(
2321
b.const(
24-
b.array_pattern([get, set]),
25-
b.call('$.validate_spread_bindings', expression, expression_text)
22+
id,
23+
b.call(
24+
'$.derived',
25+
b.thunk(b.call('$.validate_spread_bindings', expression, expression_text))
26+
)
2627
)
2728
);
2829

30+
const is_server = state.options.generate === 'server';
31+
const binding = is_server ? b.call(id) : b.call('$.get', id);
32+
33+
const get = b.thunk(b.call(b.member(binding, b.literal(0), true)));
34+
const set = b.thunk(b.call(b.member(binding, b.literal(1), true), b.id('$$value')));
2935
return { get, set };
3036
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
assert.htmlEqual(target.innerHTML, `<input><button>Toggle</button>`);
7+
8+
assert.deepEqual(logs, [false]);
9+
10+
const button = target.querySelector('button');
11+
12+
button?.click();
13+
flushSync();
14+
15+
assert.deepEqual(logs, [false, true]);
16+
}
17+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
let state = $state(false);
3+
let value = $state('hello')
4+
5+
function binding(state) {
6+
console.log(state);
7+
8+
return [
9+
() => value,
10+
(v) => value = v
11+
];
12+
}
13+
</script>
14+
15+
<input bind:value={...binding(state)} />
16+
17+
<button onclick={() => (state = !state)}>Toggle</button>

0 commit comments

Comments
 (0)