@@ -14,7 +14,7 @@ import { JSXNodeImpl, isJSXNode } from '../shared/jsx/jsx-node';
1414import { Fragment , type Props } from '../shared/jsx/jsx-runtime' ;
1515import { directGetPropsProxyProp , type PropsProxy } from '../shared/jsx/props-proxy' ;
1616import { Slot } from '../shared/jsx/slot.public' ;
17- import type { JSXNodeInternal , JSXOutput } from '../shared/jsx/types/jsx-node' ;
17+ import type { JSXNodeInternal } from '../shared/jsx/types/jsx-node' ;
1818import type { JSXChildren } from '../shared/jsx/types/jsx-qwik-attributes' ;
1919import { SSRComment , SSRRaw , SkipRender } from '../shared/jsx/utils.public' ;
2020import type { QRLInternal } from '../shared/qrl/qrl-class' ;
@@ -39,7 +39,6 @@ import {
3939 QBackRefs ,
4040 QContainerAttr ,
4141 QDefaultSlot ,
42- QScopedStyle ,
4342 QSlot ,
4443 QTemplate ,
4544 Q_PREFIX ,
@@ -85,7 +84,7 @@ import { getAttributeNamespace, getNewElementNamespaceData } from './vnode-names
8584
8685export const vnode_diff = (
8786 container : ClientContainer ,
88- jsxNode : JSXOutput ,
87+ jsxNode : JSXChildren ,
8988 vStartNode : VNode ,
9089 scopedStyleIdPrefix : string | null
9190) => {
@@ -99,8 +98,7 @@ export const vnode_diff = (
9998 */
10099 const stack : any [ ] = [ ] ;
101100
102- const asyncQueue : Array < VNode | ValueOrPromise < JSXOutput > | Promise < JSXOutput | JSXChildren > > =
103- [ ] ;
101+ const asyncQueue : Array < VNode | ValueOrPromise < JSXChildren > | Promise < JSXChildren > > = [ ] ;
104102
105103 ////////////////////////////////
106104 //// Traverse state variables
@@ -152,7 +150,7 @@ export const vnode_diff = (
152150 //////////////////////////////////////////////
153151 //////////////////////////////////////////////
154152
155- function diff ( jsxNode : JSXOutput , vStartNode : VNode ) {
153+ function diff ( jsxNode : JSXChildren , vStartNode : VNode ) {
156154 assertFalse ( vnode_isVNode ( jsxNode ) , 'JSXNode should not be a VNode' ) ;
157155 assertTrue ( vnode_isVNode ( vStartNode ) , 'vStartNode should be a VNode' ) ;
158156 vParent = vStartNode as ElementVNode | VirtualVNode ;
@@ -185,15 +183,8 @@ export const vnode_diff = (
185183 if ( currentSignal !== unwrappedSignal ) {
186184 const vHost = ( vNewNode || vCurrent ) ! ;
187185 descend (
188- resolveSignalAndDescend (
189- retryOnPromise ( ( ) =>
190- trackSignalAndAssignHost (
191- unwrappedSignal ,
192- vHost ,
193- EffectProperty . VNODE ,
194- container
195- )
196- )
186+ resolveSignalAndDescend ( ( ) =>
187+ trackSignalAndAssignHost ( unwrappedSignal , vHost , EffectProperty . VNODE , container )
197188 ) ,
198189 true
199190 ) ;
@@ -252,12 +243,19 @@ export const vnode_diff = (
252243 }
253244 }
254245
255- function resolveSignalAndDescend ( value : any ) {
256- if ( isPromise ( value ) ) {
257- asyncQueue . push ( value , vNewNode || vCurrent , null ) ;
258- return null ;
246+ function resolveSignalAndDescend ( fn : ( ) => ValueOrPromise < any > ) : ValueOrPromise < any > {
247+ try {
248+ return fn ( ) ;
249+ } catch ( e ) {
250+ // Signal threw a promise (async computed signal) - handle retry and async queue
251+ if ( isPromise ( e ) ) {
252+ // The thrown promise will resolve when the signal is ready, then retry fn() with retry logic
253+ const retryPromise = e . then ( ( ) => retryOnPromise ( fn ) ) ;
254+ asyncQueue . push ( retryPromise , vNewNode || vCurrent , null ) ;
255+ return null ;
256+ }
257+ throw e ;
259258 }
260- return value ;
261259 }
262260
263261 function advance ( ) {
@@ -544,29 +542,30 @@ export const vnode_diff = (
544542
545543 function drainAsyncQueue ( ) : ValueOrPromise < void > {
546544 while ( asyncQueue . length ) {
547- const jsxNode = asyncQueue . shift ( ) as ValueOrPromise < JSXNodeInternal > ;
545+ let jsxNode = asyncQueue . shift ( ) as ValueOrPromise < JSXChildren > ;
548546 const vHostNode = asyncQueue . shift ( ) as VNode ;
549547 const styleScopedId = asyncQueue . shift ( ) as string | null ;
548+
549+ const diffNode = ( jsxNode : JSXChildren , vHostNode : VNode , styleScopedId : string | null ) => {
550+ if ( styleScopedId ) {
551+ vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
552+ } else {
553+ diff ( jsxNode , vHostNode ) ;
554+ }
555+ } ;
556+
550557 if ( isPromise ( jsxNode ) ) {
551558 return jsxNode
552559 . then ( ( jsxNode ) => {
553- if ( styleScopedId ) {
554- vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
555- } else {
556- diff ( jsxNode , vHostNode ) ;
557- }
560+ diffNode ( jsxNode , vHostNode , styleScopedId ) ;
558561 return drainAsyncQueue ( ) ;
559562 } )
560563 . catch ( ( e ) => {
561564 container . handleError ( e , vHostNode ) ;
562565 return drainAsyncQueue ( ) ;
563566 } ) ;
564567 } else {
565- if ( styleScopedId ) {
566- vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
567- } else {
568- diff ( jsxNode , vHostNode ) ;
569- }
568+ diffNode ( jsxNode , vHostNode , styleScopedId ) ;
570569 }
571570 }
572571 }
0 commit comments