File tree 4 files changed +112
-10
lines changed
tests/runtime-runes/samples/derived-unowned-9
4 files changed +112
-10
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ ' svelte ' : patch
3
+ ---
4
+
5
+ fix: ensure unowned derived signals correctly re-connect to graph
Original file line number Diff line number Diff line change @@ -196,18 +196,20 @@ export function check_dirtiness(reaction) {
196
196
update_derived ( /** @type {Derived } */ ( dependency ) ) ;
197
197
}
198
198
199
- if ( dependency . version > reaction . version ) {
200
- return true ;
199
+ // If we are working with an unowned signal as part of an effect (due to !current_skip_reaction)
200
+ // and the version hasn't changed, we still need to check that this reaction
201
+ // is linked to the dependency source – otherwise future updates will not be caught.
202
+ if (
203
+ is_unowned &&
204
+ current_effect !== null &&
205
+ ! current_skip_reaction &&
206
+ ! dependency ?. reactions ?. includes ( reaction )
207
+ ) {
208
+ ( dependency . reactions ??= [ ] ) . push ( reaction ) ;
201
209
}
202
210
203
- if ( is_unowned ) {
204
- // TODO is there a more logical place to do this work?
205
- if ( ! current_skip_reaction && ! dependency ?. reactions ?. includes ( reaction ) ) {
206
- // If we are working with an unowned signal as part of an effect (due to !current_skip_reaction)
207
- // and the version hasn't changed, we still need to check that this reaction
208
- // if linked to the dependency source – otherwise future updates will not be caught.
209
- ( dependency . reactions ??= [ ] ) . push ( reaction ) ;
210
- }
211
+ if ( dependency . version > reaction . version ) {
212
+ return true ;
211
213
}
212
214
}
213
215
}
Original file line number Diff line number Diff line change
1
+ import { flushSync } from 'svelte' ;
2
+ import { test } from '../../test' ;
3
+
4
+ export default test ( {
5
+ mode : [ 'client' ] ,
6
+ async test ( { assert, target, logs } ) {
7
+ let [ btn1 , btn2 ] = target . querySelectorAll ( 'button' ) ;
8
+
9
+ btn1 . click ( ) ;
10
+ btn2 . click ( ) ;
11
+
12
+ flushSync ( ) ;
13
+
14
+ assert . htmlEqual (
15
+ target . innerHTML ,
16
+ `<button>a</button><button>b</button><div>1</div>\ndouble:\n2`
17
+ ) ;
18
+
19
+ btn1 . click ( ) ;
20
+ btn2 . click ( ) ;
21
+
22
+ flushSync ( ) ;
23
+
24
+ assert . htmlEqual (
25
+ target . innerHTML ,
26
+ `<button>a</button><button>b</button><div>2</div>\ndouble:\n4`
27
+ ) ;
28
+
29
+ btn1 . click ( ) ;
30
+
31
+ flushSync ( ) ;
32
+
33
+ assert . htmlEqual (
34
+ target . innerHTML ,
35
+ `<button>a</button><button>b</button><div>3</div>\ndouble:\n6`
36
+ ) ;
37
+
38
+ btn1 . click ( ) ;
39
+
40
+ flushSync ( ) ;
41
+
42
+ assert . htmlEqual (
43
+ target . innerHTML ,
44
+ `<button>a</button><button>b</button><div>4</div>\ndouble:\n8`
45
+ ) ;
46
+
47
+ btn1 . click ( ) ;
48
+
49
+ flushSync ( ) ;
50
+
51
+ assert . htmlEqual ( target . innerHTML , `<button>a</button><button>b</button><div>5</div>` ) ;
52
+
53
+ btn1 . click ( ) ;
54
+
55
+ flushSync ( ) ;
56
+
57
+ assert . htmlEqual (
58
+ target . innerHTML ,
59
+ `<button>a</button><button>b</button><div>6</div>\ndouble:\n12`
60
+ ) ;
61
+
62
+ btn1 . click ( ) ;
63
+
64
+ flushSync ( ) ;
65
+
66
+ assert . htmlEqual (
67
+ target . innerHTML ,
68
+ `<button>a</button><button>b</button><div>7</div>\ndouble:\n14`
69
+ ) ;
70
+ }
71
+ } ) ;
Original file line number Diff line number Diff line change
1
+ <script >
2
+ let count = $state (0 );
3
+
4
+ function increment () {
5
+ count += 1 ;
6
+ }
7
+
8
+ let double = $state ();
9
+ function setDerived () {
10
+ const d = $derived (count * 2 );
11
+ double = {
12
+ get v () { return d }
13
+ };
14
+ }
15
+ </script >
16
+
17
+ <button onclick ={increment }>a</button >
18
+ <button onclick ={setDerived }>b</button >
19
+
20
+ <div >{count }</div >
21
+
22
+ {#if double && count % 5 }
23
+ double: {double .v }
24
+ {/if }
You can’t perform that action at this time.
0 commit comments