@@ -1433,10 +1433,13 @@ export function prop(props, key, flags, initial) {
1433
1433
return value === undefined ? /** @type {V } */ ( initial ) : value ;
1434
1434
} ;
1435
1435
1436
+ // easy mode — prop is never written to
1436
1437
if ( ( flags & PROPS_IS_UPDATED ) === 0 ) {
1437
1438
return getter ;
1438
1439
}
1439
1440
1441
+ // intermediate mode — prop is written to, but the parent component had
1442
+ // `bind:foo` which means we can just call `$$props.foo = value` directly
1440
1443
if ( setter ) {
1441
1444
return function ( /** @type {V } */ value ) {
1442
1445
if ( arguments . length === 1 ) {
@@ -1448,41 +1451,51 @@ export function prop(props, key, flags, initial) {
1448
1451
} ;
1449
1452
}
1450
1453
1451
- var setting_from_child = false ;
1452
- var last_set_from_child = false ;
1454
+ // hard mode. this is where it gets ugly — the value in the child should
1455
+ // synchronize with the parent, but it should also be possible to temporarily
1456
+ // set the value to something else locally. to make this work, we need to
1457
+ // do a little dance.
1458
+ var from_child = false ;
1459
+ var was_from_child = false ;
1460
+
1453
1461
var s = mutable_source ( value ) ;
1454
1462
var d = derived ( ( ) => {
1455
- const from_parent = getter ( ) ;
1456
- const from_child = get ( s ) ;
1463
+ var parent_value = getter ( ) ;
1464
+ var child_value = get ( s ) ;
1457
1465
1458
- if ( setting_from_child ) {
1459
- setting_from_child = false ;
1460
- last_set_from_child = true ;
1461
- return from_child ;
1466
+ if ( from_child ) {
1467
+ from_child = false ;
1468
+ was_from_child = true ;
1469
+ return child_value ;
1462
1470
}
1463
1471
1464
- last_set_from_child = false ;
1465
- return ( s . v = from_parent ) ;
1472
+ was_from_child = false ;
1473
+ return ( s . v = parent_value ) ;
1466
1474
} ) ;
1467
1475
1468
1476
if ( ! immutable ) d . e = safe_equal ;
1469
1477
1470
1478
return function ( /** @type {V } */ value , mutation = false ) {
1471
- const current = get ( d ) ;
1479
+ var current = get ( d ) ;
1472
1480
1473
1481
// legacy nonsense — need to ensure the source is invalidated when necessary
1474
1482
if ( is_signals_recorded ) {
1475
- setting_from_child = last_set_from_child ;
1483
+ // set this so that we don't reset to the parent value if `d`
1484
+ // is invalidated because of `invalidate_inner_signals` (rather
1485
+ // than because the parent or child value changed)
1486
+ from_child = was_from_child ;
1487
+
1476
1488
getter ( ) ;
1477
1489
get ( s ) ;
1478
1490
}
1479
1491
1480
1492
if ( arguments . length > 0 ) {
1481
1493
if ( mutation || ( immutable ? value !== current : safe_not_equal ( value , current ) ) ) {
1482
- setting_from_child = true ;
1494
+ from_child = true ;
1483
1495
set ( s , mutation ? current : value ) ;
1484
1496
get ( d ) ; // force a synchronisation immediately
1485
1497
}
1498
+
1486
1499
return value ;
1487
1500
}
1488
1501
0 commit comments