@@ -176,45 +176,83 @@ export function VariableDeclaration(node, context) {
176176 const value = /** @type {Expression } */ ( args [ 0 ] ) ?? b . void0 ; // TODO do we need the void 0? can we just omit it altogether?
177177
178178 if ( rune === '$state' || rune === '$state.raw' ) {
179+ const state_declarators = [ ] ;
180+ const current_chunk = context . state . current_parallelized_chunk ;
181+ const parallelize =
182+ declarator . id . type === 'Identifier' &&
183+ context . state . analysis . instance ?. scope === context . state . scope &&
184+ value . type === 'AwaitExpression' &&
185+ can_be_parallelized ( value . argument , context . state . scope , context . state . analysis , [
186+ ...( current_chunk ?. bindings ?? [ ] ) ,
187+ ...bindings
188+ ] ) ;
179189 /**
180190 * @param {Identifier } id
191+ * @param {Expression } visited
181192 * @param {Expression } value
182193 */
183- const create_state_declarator = ( id , value ) => {
194+ const create_state_declarator = ( id , visited , value ) => {
184195 const binding = /** @type {Binding } */ ( context . state . scope . get ( id . name ) ) ;
185196 const is_state = is_state_source ( binding , context . state . analysis ) ;
186- const is_proxy = should_proxy ( value , context . state . scope ) ;
197+ const is_proxy = should_proxy ( visited , context . state . scope ) ;
198+ const compose = [ ] ;
199+ if ( parallelize ) {
200+ if ( rune === '$state' && is_proxy ) {
201+ compose . push ( b . id ( '$.proxy' ) ) ;
187202
188- if ( rune === '$state' && is_proxy ) {
189- value = b . call ( '$.proxy' , value ) ;
203+ if ( dev && ! is_state ) {
204+ compose . push (
205+ b . arrow ( [ b . id ( 'proxy' ) ] , b . call ( '$.tag_proxy' , b . id ( 'proxy' ) , b . literal ( id . name ) ) )
206+ ) ;
207+ }
208+ }
190209
191- if ( dev && ! is_state ) {
192- value = b . call ( '$.tag_proxy' , value , b . literal ( id . name ) ) ;
210+ if ( is_state ) {
211+ compose . push ( b . id ( '$.state' ) ) ;
212+ if ( dev ) {
213+ compose . push (
214+ b . arrow ( [ b . id ( 'source' ) ] , b . call ( '$.tag' , b . id ( 'source' ) , b . literal ( id . name ) ) )
215+ ) ;
216+ }
217+ }
218+ } else {
219+ if ( rune === '$state' && is_proxy ) {
220+ value = b . call ( '$.proxy' , value ) ;
221+
222+ if ( dev && ! is_state ) {
223+ value = b . call ( '$.tag_proxy' , value , b . literal ( id . name ) ) ;
224+ }
193225 }
194- }
195226
196- if ( is_state ) {
197- value = b . call ( '$.state' , value ) ;
227+ if ( is_state ) {
228+ value = b . call ( '$.state' , value ) ;
198229
199- if ( dev ) {
200- value = b . call ( '$.tag' , value , b . literal ( id . name ) ) ;
230+ if ( dev ) {
231+ value = b . call ( '$.tag' , value , b . literal ( id . name ) ) ;
232+ }
201233 }
202234 }
203235
204- return value ;
236+ return parallelize && value . type === 'AwaitExpression'
237+ ? b . call (
238+ '$.async_compose' ,
239+ /** @type {Expression } */ ( context . visit ( value . argument ) ) ,
240+ ...compose
241+ )
242+ : visited ;
205243 } ;
206244
207245 if ( declarator . id . type === 'Identifier' ) {
208246 const expression = /** @type {Expression } */ ( context . visit ( value ) ) ;
209247
210- declarations . push (
211- b . declarator ( declarator . id , create_state_declarator ( declarator . id , expression ) )
248+ state_declarators . push (
249+ b . declarator ( declarator . id , create_state_declarator ( declarator . id , expression , value ) )
212250 ) ;
213251 } else {
214252 const tmp = b . id ( context . state . scope . generate ( 'tmp' ) ) ;
215253 const { inserts, paths } = extract_paths ( declarator . id , tmp ) ;
216254
217- declarations . push (
255+ state_declarators . push (
218256 b . declarator ( tmp , /** @type {Expression } */ ( context . visit ( value ) ) ) ,
219257 ...inserts . map ( ( { id, value } ) => {
220258 id . name = context . state . scope . generate ( '$$array' ) ;
@@ -236,12 +274,36 @@ export function VariableDeclaration(node, context) {
236274 return b . declarator (
237275 path . node ,
238276 binding ?. kind === 'state' || binding ?. kind === 'raw_state'
239- ? create_state_declarator ( binding . node , value )
277+ ? create_state_declarator ( binding . node , value , path . expression )
240278 : value
241279 ) ;
242280 } )
243281 ) ;
244282 }
283+ if ( ! parallelize ) {
284+ declarations . push ( ...state_declarators ) ;
285+ } else {
286+ const declarators = state_declarators . map ( ( { id, init } ) => ( {
287+ id,
288+ init : /** @type {Expression } */ ( init )
289+ } ) ) ;
290+ if ( current_chunk && ( current_chunk . kind === node . kind || current_chunk . kind === null ) ) {
291+ current_chunk . declarators . push ( ...declarators ) ;
292+ current_chunk . bindings . push ( ...bindings ) ;
293+ current_chunk . position = position ;
294+ current_chunk . kind = node . kind ;
295+ } else {
296+ /** @type {ParallelizedChunk } */
297+ const chunk = {
298+ kind : node . kind ,
299+ declarators,
300+ position,
301+ bindings
302+ } ;
303+ context . state . current_parallelized_chunk = chunk ;
304+ context . state . parallelized_chunks . push ( chunk ) ;
305+ }
306+ }
245307
246308 continue ;
247309 }
0 commit comments