@@ -40,7 +40,7 @@ import {
4040 detectContainerSelector ,
4141 hasExplicitItemKey ,
4242} from './analyze-helpers.ts'
43- import { collectExpressionDependencies , collectTemplateSetupStatements } from './transform-attributes.ts'
43+ import { collectExpressionDependencies , collectTemplateSetupStatements , isStateDep } from './transform-attributes.ts'
4444import type { StateRefMeta } from './parse.ts'
4545import { createRequire } from 'module'
4646
@@ -684,9 +684,7 @@ function analyzeAttributes(
684684 if ( templateSetupContext && ! t . isJSXEmptyExpression ( expr ) ) {
685685 const setupStatements = collectTemplateSetupStatements ( expr , templateSetupContext )
686686 const dependencies = collectExpressionDependencies ( expr , stateRefs , setupStatements )
687- const stateDeps = dependencies . filter (
688- ( d ) => d . storeVar || ( d . pathParts . length > 0 && d . pathParts [ 0 ] !== 'props' ) ,
689- )
687+ const stateDeps = dependencies . filter ( isStateDep )
690688 if ( stateDeps . length > 0 ) {
691689 const selector = generateSelector ( elementPath )
692690 propBindings . push ( {
@@ -748,7 +746,7 @@ function analyzeAttributes(
748746 if ( isNativeElement && templateSetupContext && ! t . isJSXEmptyExpression ( expr ) ) {
749747 const setupStatements = collectTemplateSetupStatements ( expr , templateSetupContext )
750748 const dependencies = collectExpressionDependencies ( expr , stateRefs , setupStatements )
751- const stateDeps = dependencies . filter ( ( d ) => d . storeVar || ( d . pathParts . length > 0 && d . pathParts [ 0 ] !== 'props' ) )
749+ const stateDeps = dependencies . filter ( isStateDep )
752750 if ( stateDeps . length > 0 ) {
753751 const selector = generateSelector ( elementPath )
754752 propBindings . push ( {
@@ -1150,7 +1148,7 @@ function handleArrayMap(
11501148 const locStr = loc ? ` (line ${ loc . line } , col ${ loc . column } )` : ''
11511149 const err = new Error (
11521150 `[gea] Array .map() items must have a \`key\` prop on the root element${ locStr } . ` +
1153- `Add key={item.id} (or another unique identifier) to the outermost JSX element returned by the .map() callback.` ,
1151+ `Add key={item.id} (or another unique identifier) to the outermost JSX element returned by the .map() callback.` ,
11541152 )
11551153 ; ( err as any ) . __geaCompileError = true
11561154 throw err
@@ -1462,6 +1460,21 @@ function handleTextBinding(
14621460 ...( textNodeIndex !== undefined ? { textNodeIndex } : { } ) ,
14631461 } ) ) ,
14641462 )
1463+ const templateStateDeps = collectExpressionDependencies ( derivedTemplateExpr , stateRefs , setupStatements )
1464+ . filter ( isStateDep )
1465+ if ( templateStateDeps . length > 0 ) {
1466+ const stateOnlyBinding : PropBinding = {
1467+ propName : '__state__' ,
1468+ selector,
1469+ type : 'text' ,
1470+ elementPath : [ ...elementPath ] ,
1471+ expression : t . cloneNode ( derivedTemplateExpr , true ) as t . Expression ,
1472+ setupStatements : setupStatements . map ( ( s ) => t . cloneNode ( s , true ) as t . Statement ) ,
1473+ stateOnly : true ,
1474+ }
1475+ if ( textNodeIndex !== undefined ) stateOnlyBinding . textNodeIndex = textNodeIndex
1476+ propBindings . push ( stateOnlyBinding )
1477+ }
14651478 return
14661479 }
14671480 }
@@ -1480,6 +1493,25 @@ function handleTextBinding(
14801493 for ( const d of derived ) d . textNodeIndex = textNodeIndex
14811494 }
14821495 propBindings . push ( ...derived )
1496+ // When the expression also has state deps, add a stateOnly binding so the state
1497+ // observer reads this.props.X live rather than inheriting `value` from the prop
1498+ // binding's patch body (where `value` is the incoming prop value, not the new state).
1499+ const setupStatements = derived [ 0 ] . setupStatements
1500+ const stateDeps = collectExpressionDependencies ( expr as t . Expression , stateRefs , setupStatements ?? [ ] )
1501+ . filter ( isStateDep )
1502+ if ( stateDeps . length > 0 ) {
1503+ const stateOnlyBinding : PropBinding = {
1504+ propName : '__state__' ,
1505+ selector : generateSelector ( elementPath ) ,
1506+ type : 'text' ,
1507+ elementPath : [ ...elementPath ] ,
1508+ expression : t . cloneNode ( expr , true ) as t . Expression ,
1509+ setupStatements,
1510+ stateOnly : true ,
1511+ }
1512+ if ( textNodeIndex !== undefined ) stateOnlyBinding . textNodeIndex = textNodeIndex
1513+ propBindings . push ( stateOnlyBinding )
1514+ }
14831515 return
14841516 }
14851517 }
@@ -1546,7 +1578,7 @@ function handleTextBinding(
15461578 : expr
15471579 const setupStatements = collectTemplateSetupStatements ( exprToUse , templateSetupContext )
15481580 const dependencies = collectExpressionDependencies ( exprToUse , stateRefs , setupStatements )
1549- const stateDeps = dependencies . filter ( ( d ) => d . storeVar || ( d . pathParts . length > 0 && d . pathParts [ 0 ] !== 'props' ) )
1581+ const stateDeps = dependencies . filter ( isStateDep )
15501582 if ( stateDeps . length > 0 ) {
15511583 const selector = generateSelector ( elementPath )
15521584 propBindings . push ( {
@@ -1839,13 +1871,13 @@ function collectAllStateAccesses(
18391871 const setupStatements =
18401872 rootExpr && templateSetupContext
18411873 ? ( ( ) => {
1842- const collected = collectTemplateSetupStatements ( rootExpr , templateSetupContext )
1843- if ( collected . length > 0 ) return collected . map ( ( s ) => t . cloneNode ( s , true ) as t . Statement )
1844- if ( templateSetupContext . earlyReturnBarrierIndex === undefined ) return [ ]
1845- return templateSetupContext . statements
1846- . slice ( 0 , templateSetupContext . earlyReturnBarrierIndex + 1 )
1847- . map ( ( s ) => t . cloneNode ( s , true ) as t . Statement )
1848- } ) ( )
1874+ const collected = collectTemplateSetupStatements ( rootExpr , templateSetupContext )
1875+ if ( collected . length > 0 ) return collected . map ( ( s ) => t . cloneNode ( s , true ) as t . Statement )
1876+ if ( templateSetupContext . earlyReturnBarrierIndex === undefined ) return [ ]
1877+ return templateSetupContext . statements
1878+ . slice ( 0 , templateSetupContext . earlyReturnBarrierIndex + 1 )
1879+ . map ( ( s ) => t . cloneNode ( s , true ) as t . Statement )
1880+ } ) ( )
18491881 : [ ]
18501882 const prog = t . program ( [ ...setupStatements , t . expressionStatement ( expr ) ] )
18511883
0 commit comments