1- /** @import { BlockStatement, Statement, Pattern , Expression } from 'estree' */
1+ /** @import { BlockStatement, Statement, Property , Expression } from 'estree' */
22/** @import { AST } from '#compiler' */
33/** @import { ComponentContext } from '../types' */
44
@@ -11,27 +11,45 @@ export function SvelteBoundary(node, context) {
1111 const nodes = [ ] ;
1212 /** @type {Statement[] } */
1313 const snippet_statements = [ ] ;
14- /** @type {Expression } */
15- let failed_param = b . literal ( null ) ;
16- /** @type {Expression | null } */
17- let onerror = null ;
14+ /** @type {Array<Property[] | Expression> } */
15+ const props_and_spreads = [ ] ;
16+
17+ let has_spread = false ;
18+
19+ const push_prop = ( /** @type {Property } */ prop ) => {
20+ let current = props_and_spreads . at ( - 1 ) ;
21+ if ( Array . isArray ( current ) ) {
22+ current . push ( prop ) ;
23+ }
24+ const arr = [ prop ] ;
25+ props_and_spreads . push ( arr ) ;
26+ } ;
1827
1928 for ( const attribute of node . attributes ) {
29+ if ( attribute . type === 'SpreadAttribute' ) {
30+ has_spread = true ;
31+ props_and_spreads . push ( attribute . expression ) ;
32+ continue ;
33+ }
2034 if (
2135 attribute . type !== 'Attribute' ||
2236 attribute . value === true ||
2337 Array . isArray ( attribute . value )
2438 ) {
2539 continue ;
2640 }
27- if ( attribute . name === 'onerror' ) {
28- onerror = /** @type {Expression } */ (
29- context . visit ( attribute . value . expression , context . state )
30- ) ;
31- } else if ( attribute . name === 'failed' ) {
32- failed_param = /** @type {Expression } */ (
41+ if ( attribute . name === 'onerror' || attribute . name === 'failed' ) {
42+ const value = /** @type {Expression } */ (
3343 context . visit ( attribute . value . expression , context . state )
3444 ) ;
45+
46+ if ( attribute . metadata . expression . has_state ) {
47+ push_prop (
48+ b . prop ( 'get' , b . id ( attribute . name ) , b . function ( null , [ ] , b . block ( [ b . return ( value ) ] ) ) )
49+ ) ;
50+ } else {
51+ push_prop ( b . prop ( 'init' , b . id ( attribute . name ) , value ) ) ;
52+ }
3553 }
3654 }
3755
@@ -41,7 +59,8 @@ export function SvelteBoundary(node, context) {
4159 const init = [ ] ;
4260 const block_state = { ...context . state , init } ;
4361 context . visit ( child , block_state ) ;
44- failed_param = b . id ( 'failed' ) ;
62+ const current = props_and_spreads . at ( - 1 ) ?? props_and_spreads . push ( [ ] ) ;
63+ push_prop ( b . prop ( 'init' , b . id ( 'failed' ) , b . id ( 'failed' ) ) ) ;
4564 snippet_statements . push ( ...init ) ;
4665 } else {
4766 nodes . push ( child ) ;
@@ -58,14 +77,16 @@ export function SvelteBoundary(node, context) {
5877 )
5978 ) ;
6079
80+ const props_expression =
81+ ! has_spread && Array . isArray ( props_and_spreads [ 0 ] )
82+ ? b . object ( props_and_spreads [ 0 ] )
83+ : b . call (
84+ '$.spread_props' ,
85+ ...props_and_spreads . map ( ( p ) => ( Array . isArray ( p ) ? b . object ( p ) : p ) )
86+ ) ;
87+
6188 const boundary = b . stmt (
62- b . call (
63- '$.boundary' ,
64- context . state . node ,
65- b . arrow ( [ b . id ( '$$anchor' ) ] , block ) ,
66- failed_param ,
67- ! onerror ? b . literal ( null ) : onerror
68- )
89+ b . call ( '$.boundary' , context . state . node , b . arrow ( [ b . id ( '$$anchor' ) ] , block ) , props_expression )
6990 ) ;
7091
7192 context . state . template . push ( '<!>' ) ;
0 commit comments