@@ -224,20 +224,75 @@ describe('signals', () => {
224224 } ;
225225 } ) ;
226226
227- test ( 'effects correctly handle unowned derived values that do not change ' , ( ) => {
228- const log : number [ ] = [ ] ;
227+ test ( 'https://perf.js.hyoo.ru/#!bench=9h2as6_u0mfnn #2 ' , ( ) => {
228+ let res : number [ ] = [ ] ;
229229
230- let count = state ( 0 ) ;
231- const read = ( ) => {
232- const x = derived ( ( ) => ( { count : $ . get ( count ) } ) ) ;
233- return $ . get ( x ) ;
230+ const numbers = Array . from ( { length : 2 } , ( _ , i ) => i ) ;
231+ const fib = ( n : number ) : number => ( n < 2 ? 1 : fib ( n - 1 ) + fib ( n - 2 ) ) ;
232+ const hard = ( n : number , l : string ) => n + fib ( 16 ) ;
233+
234+ const A = state ( 0 ) ;
235+ const B = state ( 0 ) ;
236+
237+ return ( ) => {
238+ const C = derived ( ( ) => ( $ . get ( A ) % 2 ) + ( $ . get ( B ) % 2 ) ) ;
239+ const D = derived ( ( ) => numbers . map ( ( i ) => i + ( $ . get ( A ) % 2 ) - ( $ . get ( B ) % 2 ) ) ) ;
240+ const E = derived ( ( ) => hard ( $ . get ( C ) + $ . get ( A ) + $ . get ( D ) [ 0 ] ! , 'E' ) ) ;
241+ const F = derived ( ( ) => hard ( $ . get ( D ) [ 0 ] ! && $ . get ( B ) , 'F' ) ) ;
242+ const G = derived ( ( ) => $ . get ( C ) + ( $ . get ( C ) || $ . get ( E ) % 2 ) + $ . get ( D ) [ 0 ] ! + $ . get ( F ) ) ;
243+
244+ const destroy = effect_root ( ( ) => {
245+ effect ( ( ) => {
246+ res . push ( hard ( $ . get ( G ) , 'H' ) ) ;
247+ } ) ;
248+ effect ( ( ) => {
249+ res . push ( $ . get ( G ) ) ;
250+ } ) ;
251+ effect ( ( ) => {
252+ res . push ( hard ( $ . get ( F ) , 'J' ) ) ;
253+ } ) ;
254+ } ) ;
255+
256+ flushSync ( ) ;
257+
258+ let i = 2 ;
259+ while ( -- i ) {
260+ res . length = 0 ;
261+ set ( B , 1 ) ;
262+ set ( A , 1 + i * 2 ) ;
263+ flushSync ( ) ;
264+
265+ set ( A , 2 + i * 2 ) ;
266+ set ( B , 2 ) ;
267+ flushSync ( ) ;
268+
269+ assert . equal ( res . length , 4 ) ;
270+ assert . deepEqual ( res , [ 3198 , 1601 , 3195 , 1598 ] ) ;
271+ }
272+
273+ destroy ( ) ;
274+ assert ( A . reactions === null ) ;
275+ assert ( B . reactions === null ) ;
234276 } ;
235- const derivedCount = derived ( ( ) => read ( ) . count ) ;
236- user_effect ( ( ) => {
237- log . push ( $ . get ( derivedCount ) ) ;
238- } ) ;
277+ } ) ;
278+
279+ test ( 'effects correctly handle unowned derived values that do not change' , ( ) => {
280+ const log : number [ ] = [ ] ;
239281
240282 return ( ) => {
283+ let count = state ( 0 ) ;
284+ const read = ( ) => {
285+ const x = derived ( ( ) => ( { count : $ . get ( count ) } ) ) ;
286+ return $ . get ( x ) ;
287+ } ;
288+ const derivedCount = derived ( ( ) => read ( ) . count ) ;
289+
290+ const destroy = effect_root ( ( ) => {
291+ user_effect ( ( ) => {
292+ log . push ( $ . get ( derivedCount ) ) ;
293+ } ) ;
294+ } ) ;
295+
241296 flushSync ( ( ) => set ( count , 1 ) ) ;
242297 // Ensure we're not leaking consumers
243298 assert . deepEqual ( count . reactions ?. length , 1 ) ;
@@ -248,6 +303,8 @@ describe('signals', () => {
248303 // Ensure we're not leaking consumers
249304 assert . deepEqual ( count . reactions ?. length , 1 ) ;
250305 assert . deepEqual ( log , [ 0 , 1 , 2 , 3 ] ) ;
306+
307+ destroy ( ) ;
251308 } ;
252309 } ) ;
253310
@@ -343,25 +400,69 @@ describe('signals', () => {
343400 } ;
344401 } ) ;
345402
346- let some_state = state ( { } ) ;
347- let some_deps = derived ( ( ) => {
348- return [ $ . get ( some_state ) ] ;
349- } ) ;
350-
351403 test ( 'two effects with an unowned derived that has some dependencies' , ( ) => {
352404 const log : Array < Array < any > > = [ ] ;
353405
354- render_effect ( ( ) => {
355- log . push ( $ . get ( some_deps ) ) ;
356- } ) ;
406+ return ( ) => {
407+ let some_state = state ( { } ) ;
408+ let some_deps = derived ( ( ) => {
409+ return [ $ . get ( some_state ) ] ;
410+ } ) ;
411+ let destroy2 : any ;
357412
358- render_effect ( ( ) => {
359- log . push ( $ . get ( some_deps ) ) ;
360- } ) ;
413+ const destroy = effect_root ( ( ) => {
414+ render_effect ( ( ) => {
415+ $ . untrack ( ( ) => {
416+ log . push ( $ . get ( some_deps ) ) ;
417+ } ) ;
418+ } ) ;
361419
362- return ( ) => {
420+ destroy2 = effect_root ( ( ) => {
421+ render_effect ( ( ) => {
422+ log . push ( $ . get ( some_deps ) ) ;
423+ } ) ;
424+
425+ render_effect ( ( ) => {
426+ log . push ( $ . get ( some_deps ) ) ;
427+ } ) ;
428+ } ) ;
429+ } ) ;
430+
431+ set ( some_state , { } ) ;
432+ flushSync ( ) ;
433+
434+ assert . deepEqual ( log , [ [ { } ] , [ { } ] , [ { } ] , [ { } ] , [ { } ] ] ) ;
435+
436+ destroy2 ( ) ;
437+
438+ set ( some_state , { } ) ;
363439 flushSync ( ) ;
364- assert . deepEqual ( log , [ [ { } ] , [ { } ] ] ) ;
440+
441+ assert . deepEqual ( log , [ [ { } ] , [ { } ] , [ { } ] , [ { } ] , [ { } ] ] ) ;
442+
443+ log . length = 0
444+
445+ const destroy3 = effect_root ( ( ) => {
446+ render_effect ( ( ) => {
447+ $ . untrack ( ( ) => {
448+ log . push ( $ . get ( some_deps ) ) ;
449+ } ) ;
450+ log . push ( $ . get ( some_deps ) ) ;
451+ } ) ;
452+ } ) ;
453+
454+ set ( some_state , { } ) ;
455+ flushSync ( ) ;
456+
457+ assert . deepEqual ( log , [ [ { } ] , [ { } ] , [ { } ] , [ { } ] ] ) ;
458+
459+ destroy3 ( ) ;
460+
461+ assert ( some_state . reactions === null ) ;
462+
463+ destroy ( ) ;
464+
465+ assert ( some_state . reactions === null ) ;
365466 } ;
366467 } ) ;
367468
0 commit comments