@@ -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' ;
@@ -85,7 +85,7 @@ import { getAttributeNamespace, getNewElementNamespaceData } from './vnode-names
8585
8686export const vnode_diff = (
8787 container : ClientContainer ,
88- jsxNode : JSXOutput ,
88+ jsxNode : JSXChildren ,
8989 vStartNode : VNode ,
9090 scopedStyleIdPrefix : string | null
9191) => {
@@ -99,8 +99,7 @@ export const vnode_diff = (
9999 */
100100 const stack : any [ ] = [ ] ;
101101
102- const asyncQueue : Array < VNode | ValueOrPromise < JSXOutput > | Promise < JSXOutput | JSXChildren > > =
103- [ ] ;
102+ const asyncQueue : Array < VNode | ValueOrPromise < JSXChildren > | Promise < JSXChildren > > = [ ] ;
104103
105104 ////////////////////////////////
106105 //// Traverse state variables
@@ -152,7 +151,7 @@ export const vnode_diff = (
152151 //////////////////////////////////////////////
153152 //////////////////////////////////////////////
154153
155- function diff ( jsxNode : JSXOutput , vStartNode : VNode ) {
154+ function diff ( jsxNode : JSXChildren , vStartNode : VNode ) {
156155 assertFalse ( vnode_isVNode ( jsxNode ) , 'JSXNode should not be a VNode' ) ;
157156 assertTrue ( vnode_isVNode ( vStartNode ) , 'vStartNode should be a VNode' ) ;
158157 vParent = vStartNode as ElementVNode | VirtualVNode ;
@@ -185,15 +184,8 @@ export const vnode_diff = (
185184 if ( currentSignal !== unwrappedSignal ) {
186185 const vHost = ( vNewNode || vCurrent ) ! ;
187186 descend (
188- resolveSignalAndDescend (
189- retryOnPromise ( ( ) =>
190- trackSignalAndAssignHost (
191- unwrappedSignal ,
192- vHost ,
193- EffectProperty . VNODE ,
194- container
195- )
196- )
187+ resolveSignalAndDescend ( ( ) =>
188+ trackSignalAndAssignHost ( unwrappedSignal , vHost , EffectProperty . VNODE , container )
197189 ) ,
198190 true
199191 ) ;
@@ -252,12 +244,19 @@ export const vnode_diff = (
252244 }
253245 }
254246
255- function resolveSignalAndDescend ( value : any ) {
256- if ( isPromise ( value ) ) {
257- asyncQueue . push ( value , vNewNode || vCurrent , null ) ;
258- return null ;
247+ function resolveSignalAndDescend ( fn : ( ) => ValueOrPromise < any > ) : ValueOrPromise < any > {
248+ try {
249+ return fn ( ) ;
250+ } catch ( e ) {
251+ // Signal threw a promise (async computed signal) - handle retry and async queue
252+ if ( isPromise ( e ) ) {
253+ // The thrown promise will resolve when the signal is ready, then retry fn() with retry logic
254+ const retryPromise = e . then ( ( ) => retryOnPromise ( fn ) ) ;
255+ asyncQueue . push ( retryPromise , vNewNode || vCurrent , null ) ;
256+ return null ;
257+ }
258+ throw e ;
259259 }
260- return value ;
261260 }
262261
263262 function advance ( ) {
@@ -544,29 +543,30 @@ export const vnode_diff = (
544543
545544 function drainAsyncQueue ( ) : ValueOrPromise < void > {
546545 while ( asyncQueue . length ) {
547- const jsxNode = asyncQueue . shift ( ) as ValueOrPromise < JSXNodeInternal > ;
546+ let jsxNode = asyncQueue . shift ( ) as ValueOrPromise < JSXChildren > ;
548547 const vHostNode = asyncQueue . shift ( ) as VNode ;
549548 const styleScopedId = asyncQueue . shift ( ) as string | null ;
549+
550+ const diffNode = ( jsxNode : JSXChildren , vHostNode : VNode , styleScopedId : string | null ) => {
551+ if ( styleScopedId ) {
552+ vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
553+ } else {
554+ diff ( jsxNode , vHostNode ) ;
555+ }
556+ } ;
557+
550558 if ( isPromise ( jsxNode ) ) {
551559 return jsxNode
552560 . then ( ( jsxNode ) => {
553- if ( styleScopedId ) {
554- vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
555- } else {
556- diff ( jsxNode , vHostNode ) ;
557- }
561+ diffNode ( jsxNode , vHostNode , styleScopedId ) ;
558562 return drainAsyncQueue ( ) ;
559563 } )
560564 . catch ( ( e ) => {
561565 container . handleError ( e , vHostNode ) ;
562566 return drainAsyncQueue ( ) ;
563567 } ) ;
564568 } else {
565- if ( styleScopedId ) {
566- vnode_diff ( container , jsxNode , vHostNode , addComponentStylePrefix ( styleScopedId ) ) ;
567- } else {
568- diff ( jsxNode , vHostNode ) ;
569- }
569+ diffNode ( jsxNode , vHostNode , styleScopedId ) ;
570570 }
571571 }
572572 }
@@ -1280,15 +1280,7 @@ export const vnode_diff = (
12801280 * deleted.
12811281 */
12821282 ( host as VirtualVNode ) . flags &= ~ VNodeFlags . Deleted ;
1283- // container.$scheduler$(ChoreType.COMPONENT, host, componentQRL, vNodeProps);
1284-
1285- try {
1286- const jsxOutput = executeComponent ( container , host , host , componentQRL , vNodeProps ) ;
1287- const styleScopedId = container . getHostProp < string > ( host , QScopedStyle ) ;
1288- asyncQueue . push ( jsxOutput , host , styleScopedId ) ;
1289- } catch ( e ) {
1290- container . handleError ( e , host ) ;
1291- }
1283+ container . $scheduler$ ( ChoreType . COMPONENT , host , componentQRL , vNodeProps ) ;
12921284 }
12931285 }
12941286 descendContentToProject ( jsxChildren , host ) ;
0 commit comments