@@ -38,6 +38,7 @@ export type JSONValue =
3838 | $ReadOnlyArray < JSONValue > ;
3939
4040const PENDING = 'pending' ;
41+ const BLOCKED = 'blocked' ;
4142const RESOLVED_MODEL = 'resolved_model' ;
4243const RESOLVED_MODULE = 'resolved_module' ;
4344const INITIALIZED = 'fulfilled' ;
@@ -50,6 +51,13 @@ type PendingChunk<T> = {
5051 _response : Response ,
5152 then ( resolve : ( T ) => mixed , reject : ( mixed ) => mixed ) : void ,
5253} ;
54+ type BlockedChunk < T > = {
55+ status : 'blocked' ,
56+ value : null | Array < ( T ) => mixed > ,
57+ reason : null | Array < ( mixed ) => mixed > ,
58+ _response : Response ,
59+ then ( resolve : ( T ) => mixed , reject : ( mixed ) => mixed ) : void ,
60+ } ;
5361type ResolvedModelChunk < T > = {
5462 status : 'resolved_model' ,
5563 value : UninitializedModel ,
@@ -80,6 +88,7 @@ type ErroredChunk<T> = {
8088} ;
8189type SomeChunk < T > =
8290 | PendingChunk < T >
91+ | BlockedChunk < T >
8392 | ResolvedModelChunk < T >
8493 | ResolvedModuleChunk < T >
8594 | InitializedChunk < T >
@@ -115,6 +124,7 @@ Chunk.prototype.then = function<T>(
115124 resolve ( chunk . value ) ;
116125 break ;
117126 case PENDING :
127+ case BLOCKED :
118128 if ( resolve ) {
119129 if ( chunk . value === null ) {
120130 chunk . value = [ ] ;
@@ -159,8 +169,9 @@ function readChunk<T>(chunk: SomeChunk<T>): T {
159169 case INITIALIZED :
160170 return chunk . value ;
161171 case PENDING :
172+ case BLOCKED :
162173 // eslint-disable-next-line no-throw-literal
163- throw ( chunk : Thenable < T > ) ;
174+ throw ( ( chunk : any ) : Thenable < T > ) ;
164175 default :
165176 throw chunk . reason ;
166177 }
@@ -177,6 +188,11 @@ function createPendingChunk<T>(response: Response): PendingChunk<T> {
177188 return new Chunk ( PENDING , null , null , response ) ;
178189}
179190
191+ function createBlockedChunk< T > (response: Response): BlockedChunk< T > {
192+ // $FlowFixMe Flow doesn't support functions as constructors
193+ return new Chunk ( BLOCKED , null , null , response ) ;
194+ }
195+
180196function createErrorChunk< T > (
181197 response: Response,
182198 error: Error,
@@ -210,6 +226,7 @@ function wakeChunkIfInitialized<T>(
210226 wakeChunk ( resolveListeners , chunk . value ) ;
211227 break ;
212228 case PENDING :
229+ case BLOCKED :
213230 chunk . value = resolveListeners ;
214231 chunk . reason = rejectListeners ;
215232 break ;
@@ -222,7 +239,7 @@ function wakeChunkIfInitialized<T>(
222239}
223240
224241function triggerErrorOnChunk< T > (chunk: SomeChunk< T > , error: mixed): void {
225- if ( chunk . status !== PENDING ) {
242+ if ( chunk . status !== PENDING && chunk . status !== BLOCKED ) {
226243 // We already resolved. We didn't expect to see this.
227244 return ;
228245 }
@@ -278,7 +295,7 @@ function resolveModuleChunk<T>(
278295 chunk: SomeChunk< T > ,
279296 value: ModuleReference< T > ,
280297): void {
281- if ( chunk . status !== PENDING ) {
298+ if ( chunk . status !== PENDING && chunk . status !== BLOCKED ) {
282299 // We already resolved. We didn't expect to see this.
283300 return ;
284301 }
@@ -308,11 +325,11 @@ function initializeModelChunk<T>(chunk: ResolvedModelChunk<T>): void {
308325 ) {
309326 initializingChunkBlockedModel . value = value ;
310327 // We discovered new dependencies on modules that are not yet resolved.
311- // We have to return to the PENDING state until they're resolved.
312- const pendingChunk : PendingChunk < T > = ( chunk : any ) ;
313- pendingChunk . status = PENDING ;
314- pendingChunk . value = null ;
315- pendingChunk . reason = null ;
328+ // We have to go the BLOCKED state until they're resolved.
329+ const blockedChunk : BlockedChunk < T > = ( chunk : any ) ;
330+ blockedChunk . status = BLOCKED ;
331+ blockedChunk . value = null ;
332+ blockedChunk . reason = null ;
316333 } else {
317334 const initializedChunk : InitializedChunk < T > = ( chunk : any ) ;
318335 initializedChunk . status = INITIALIZED ;
@@ -348,7 +365,9 @@ export function reportGlobalError(response: Response, error: Error): void {
348365 // If this chunk was already resolved or errored, it won't
349366 // trigger an error but if it wasn't then we need to
350367 // because we won't be getting any new data to resolve it.
351- triggerErrorOnChunk ( chunk , error ) ;
368+ if ( chunk . status === PENDING ) {
369+ triggerErrorOnChunk ( chunk , error ) ;
370+ }
352371 } ) ;
353372}
354373
@@ -433,7 +452,7 @@ function createModelResolver<T>(
433452 parentObject [ key ] = value ;
434453 blocked . deps -- ;
435454 if ( blocked . deps === 0 ) {
436- if ( chunk . status !== PENDING ) {
455+ if ( chunk . status !== BLOCKED ) {
437456 return ;
438457 }
439458 const resolveListeners = chunk . value ;
@@ -480,6 +499,7 @@ export function parseModelString(
480499 case INITIALIZED :
481500 return chunk . value ;
482501 case PENDING :
502+ case BLOCKED :
483503 const parentChunk = initializingChunk ;
484504 chunk . then (
485505 createModelResolver ( parentChunk , parentObject , key ) ,
@@ -573,21 +593,28 @@ export function resolveModule(
573593 // that we'll need them.
574594 const promise = preloadModule ( moduleReference ) ;
575595 if ( promise ) {
576- let pendingChunk ;
596+ let blockedChunk : BlockedChunk < any > ;
577597 if ( ! chunk ) {
578- pendingChunk = createPendingChunk ( response ) ;
579- chunks . set ( id , pendingChunk ) ;
598+ // Technically, we should just treat promise as the chunk in this
599+ // case. Because it'll just behave as any other promise.
600+ blockedChunk = createBlockedChunk ( response ) ;
601+ chunks . set ( id , blockedChunk ) ;
580602 } else {
581- pendingChunk = chunk ;
603+ // This can't actually happen because we don't have any forward
604+ // references to modules.
605+ blockedChunk = ( chunk : any ) ;
606+ blockedChunk . status = BLOCKED ;
582607 }
583608 promise . then (
584- ( ) => resolveModuleChunk ( pendingChunk , moduleReference ) ,
585- error => triggerErrorOnChunk ( pendingChunk , error ) ,
609+ ( ) => resolveModuleChunk ( blockedChunk , moduleReference ) ,
610+ error => triggerErrorOnChunk ( blockedChunk , error ) ,
586611 ) ;
587612 } else {
588613 if ( ! chunk ) {
589614 chunks . set ( id , createResolvedModuleChunk ( response , moduleReference ) ) ;
590615 } else {
616+ // This can't actually happen because we don't have any forward
617+ // references to modules.
591618 resolveModuleChunk ( chunk , moduleReference ) ;
592619 }
593620 }
0 commit comments