@@ -6,8 +6,14 @@ import { assertTrue } from '../shared/error/assert';
66import { QError , qError } from '../shared/error/error' ;
77import { ERROR_CONTEXT , isRecoverable } from '../shared/error/error-handling' ;
88import type { QRL } from '../shared/qrl/qrl.public' ;
9- import { wrapDeserializerProxy } from '../shared/serdes/deser-proxy ' ;
9+ import { eagerDeserializeStateIterator } from '../shared/serdes/inflate ' ;
1010import { getObjectById , parseQRL , preprocessState } from '../shared/serdes/index' ;
11+ import {
12+ createMacroTask ,
13+ runYieldingIterator ,
14+ scheduleYieldingIterator ,
15+ type YieldingIteratorState ,
16+ } from '../shared/platform/next-tick' ;
1117import { _SharedContainer } from '../shared/shared-container' ;
1218import { QContainerValue , type HostElement , type ObjToProxyMap } from '../shared/types' ;
1319import { EMPTY_ARRAY } from '../shared/utils/flyweight' ;
@@ -84,6 +90,90 @@ export const isDomContainer = (container: any): container is DomContainer => {
8490 return container instanceof DomContainer ;
8591} ;
8692
93+ interface ProcessContainerDataState extends YieldingIteratorState { }
94+
95+ export const processContainerData = ( container : IClientContainer ) : void => {
96+ const domContainer = container as DomContainer ;
97+ if ( domContainer . $containerDataStarted$ || domContainer . $containerDataReady$ ) {
98+ return ;
99+ }
100+ domContainer . $containerDataStarted$ = true ;
101+ processVNodeData ( domContainer . document ) ;
102+ onVNodeDataReady ( domContainer . document , ( ) => {
103+ if (
104+ ! domContainer . $containerDataStarted$ ||
105+ domContainer . $containerDataReady$ ||
106+ domContainer . element . qContainer !== domContainer
107+ ) {
108+ return ;
109+ }
110+ const state : ProcessContainerDataState = {
111+ $iterator$ : domContainer . $processContainerData$ ( ) ,
112+ $schedule$ : undefined ! ,
113+ $scheduled$ : false ,
114+ } ;
115+ state . $schedule$ = createMacroTask ( ( ) =>
116+ runYieldingIterator (
117+ state ,
118+ ( ) =>
119+ domContainer . $containerDataState$ === state &&
120+ domContainer . element . qContainer === domContainer ,
121+ ( ) => markContainerDataReady ( domContainer ) ,
122+ ( ) => {
123+ domContainer . $containerDataStarted$ = false ;
124+ domContainer . $containerDataState$ = undefined ;
125+ }
126+ )
127+ ) ;
128+ domContainer . $containerDataState$ = state ;
129+ scheduleYieldingIterator ( state ) ;
130+ } ) ;
131+ } ;
132+
133+ export const onContainerDataReady = ( container : IClientContainer , callback : ( ) => void ) : void => {
134+ const domContainer = container as DomContainer ;
135+ if ( domContainer . $containerDataReady$ ) {
136+ callback ( ) ;
137+ } else {
138+ processContainerData ( domContainer ) ;
139+ ( domContainer . $containerDataCallbacks$ ||= [ ] ) . push ( callback ) ;
140+ }
141+ } ;
142+
143+ export const whenContainerDataReady = < T > (
144+ container : IClientContainer ,
145+ callback : ( ) => T | Promise < T >
146+ ) : T | Promise < T > => {
147+ const domContainer = container as DomContainer ;
148+ if ( domContainer . $containerDataReady$ ) {
149+ return callback ( ) ;
150+ }
151+ return new Promise < T > ( ( resolve , reject ) => {
152+ onContainerDataReady ( domContainer , ( ) => {
153+ try {
154+ resolve ( callback ( ) ) ;
155+ } catch ( error ) {
156+ reject ( error ) ;
157+ }
158+ } ) ;
159+ } ) ;
160+ } ;
161+
162+ function markContainerDataReady ( container : DomContainer ) : void {
163+ if ( container . $containerDataReady$ ) {
164+ return ;
165+ }
166+ container . $containerDataReady$ = true ;
167+ container . $containerDataState$ = undefined ;
168+ const callbacks = container . $containerDataCallbacks$ ;
169+ container . $containerDataCallbacks$ = undefined ;
170+ if ( callbacks ) {
171+ for ( let i = 0 ; i < callbacks . length ; i ++ ) {
172+ callbacks [ i ] ( ) ;
173+ }
174+ }
175+ }
176+
87177/** @internal */
88178export class DomContainer extends _SharedContainer implements IClientContainer {
89179 public element : ContainerElement ;
@@ -96,6 +186,10 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
96186 public $instanceHash$ : string ;
97187 public $forwardRefs$ : Array < number > | null = null ;
98188 public vNodeLocate : ( id : string | Element ) => VNode = ( id ) => vnode_locate ( this . rootVNode , id ) ;
189+ public $containerDataStarted$ = false ;
190+ public $containerDataReady$ = false ;
191+ public $containerDataState$ ?: ProcessContainerDataState ;
192+ public $containerDataCallbacks$ ?: Array < ( ) => void > ;
99193
100194 private $rawStateData$ : unknown [ ] ;
101195 private $stateData$ : unknown [ ] ;
@@ -121,10 +215,10 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
121215 this . $setServerData$ ( ) ;
122216 element . qContainer = this ;
123217 ( element as any ) . qDestroy = ( ) => this . $destroy$ ( ) ;
124- onVNodeDataReady ( document , ( ) => this . $finalizeResume$ ( ) ) ;
218+ processContainerData ( this ) ;
125219 }
126220
127- private $finalizeResume $( ) : void {
221+ * $processContainerData $( ) : Generator < void , void , void > {
128222 const element = this . element ;
129223 if ( element . qContainer !== this ) {
130224 return ;
@@ -134,7 +228,8 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
134228 const lastState = qwikStates [ qwikStates . length - 1 ] ;
135229 this . $rawStateData$ = JSON . parse ( lastState . textContent ! ) ;
136230 preprocessState ( this . $rawStateData$ , this ) ;
137- this . $stateData$ = wrapDeserializerProxy ( this , this . $rawStateData$ ) as unknown [ ] ;
231+ this . $stateData$ = Array ( this . $rawStateData$ . length / 2 ) ;
232+ yield * eagerDeserializeStateIterator ( this , this . $rawStateData$ , this . $stateData$ ) ;
138233 }
139234 this . $hoistStyles$ ( ) ;
140235 element . setAttribute ( QContainerAttr , QContainerValue . RESUMED ) ;
@@ -160,6 +255,10 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
160255 document . qVNodeDataReady = false ;
161256 document . qVNodeDataState = undefined ;
162257 document . qVNodeDataCallbacks = undefined ;
258+ this . $containerDataStarted$ = false ;
259+ this . $containerDataReady$ = false ;
260+ this . $containerDataState$ = undefined ;
261+ this . $containerDataCallbacks$ = undefined ;
163262 }
164263
165264 /**
0 commit comments