File tree Expand file tree Collapse file tree 5 files changed +41
-20
lines changed
src/internal/client/reactivity
tests/runtime-runes/samples/async-resolve-stale Expand file tree Collapse file tree 5 files changed +41
-20
lines changed Original file line number Diff line number Diff line change 11/** @import { Effect, TemplateNode, Value } from '#client' */
2- import { DESTROYED } from '#client/constants' ;
2+ import { DESTROYED , STALE_REACTION } from '#client/constants' ;
33import { DEV } from 'esm-env' ;
44import {
55 component_context ,
Original file line number Diff line number Diff line change @@ -76,6 +76,8 @@ let is_flushing = false;
7676export let is_flushing_sync = false ;
7777
7878export class Batch {
79+ committed = false ;
80+
7981 /**
8082 * The current values of any sources that are updated in this batch
8183 * They keys of this map are identical to `this.#previous`
@@ -399,6 +401,7 @@ export class Batch {
399401 batch_values = previous_batch_values ;
400402 }
401403
404+ this . committed = true ;
402405 batches . delete ( this ) ;
403406
404407 this . #deferred?. resolve ( ) ;
Original file line number Diff line number Diff line change @@ -127,7 +127,17 @@ export function async_derived(fn, location) {
127127 // If this code is changed at some point, make sure to still access the then property
128128 // of fn() to read any signals it might access, so that we track them as dependencies.
129129 // We call `unset_context` to undo any `save` calls that happen inside `fn()`
130- Promise . resolve ( fn ( ) ) . then ( d . resolve , d . reject ) . then ( unset_context ) ;
130+ Promise . resolve ( fn ( ) )
131+ . then ( d . resolve , d . reject )
132+ . then ( ( ) => {
133+ if ( batch === current_batch && batch . committed ) {
134+ // if the batch was rejected as stale, we need to cleanup
135+ // after any `$.save(...)` calls inside `fn()`
136+ batch . deactivate ( ) ;
137+ }
138+
139+ unset_context ( ) ;
140+ } ) ;
131141 } catch ( error ) {
132142 d . reject ( error ) ;
133143 unset_context ( ) ;
Original file line number Diff line number Diff line change @@ -21,5 +21,9 @@ export default test({
2121 input . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
2222 await macrotask ( 6 ) ;
2323 assert . htmlEqual ( target . innerHTML , '<input> 3 | 12' ) ;
24+ input . value = '' ;
25+ input . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
26+ await macrotask ( ) ;
27+ assert . htmlEqual ( target . innerHTML , '<input> 4 | ' ) ;
2428 }
2529} ) ;
Original file line number Diff line number Diff line change 11<script >
22 let count = $state (0 );
33 let value = $state (' ' );
4- let prev;
54
6- function asd (v ) {
7- const r = Promise .withResolvers ();
5+ let resolver;
86
9- if (prev || v === ' ' ) {
10- Promise .resolve ().then (async () => {
11- count++ ;
12- r .resolve (v);
13- await new Promise (r => setTimeout (r, 0 ));
14- // TODO with a microtask like below it still throws a mutation error
15- // await Promise.resolve();
16- prev? .resolve ();
17- });
18- } else {
19- prev = Promise .withResolvers ();
20- prev .promise .then (() => {
21- count++ ;
22- r .resolve (v)
23- });
7+ function asd (v ) {
8+ let r = Promise .withResolvers ();
9+
10+ function update_and_resolve (){
11+ count++ ;
12+ r .resolve (v);
2413 }
2514
15+ // make sure the second promise resolve before the first one
16+ if (resolver){
17+ new Promise (r => {
18+ setTimeout (r);
19+ }).then (update_and_resolve).then (()=> {
20+ setTimeout (()=> {
21+ resolver ();
22+ resolver = null ;
23+ });
24+ });
25+ }else if (v){
26+ resolver = update_and_resolve;
27+ }else {
28+ Promise .resolve ().then (update_and_resolve);
29+ }
2630 return r .promise ;
2731 }
2832
You can’t perform that action at this time.
0 commit comments