@@ -38,6 +38,7 @@ export type JSONValue =
38
38
| $ReadOnlyArray < JSONValue > ;
39
39
40
40
const PENDING = 'pending' ;
41
+ const BLOCKED = 'blocked' ;
41
42
const RESOLVED_MODEL = 'resolved_model' ;
42
43
const RESOLVED_MODULE = 'resolved_module' ;
43
44
const INITIALIZED = 'fulfilled' ;
@@ -50,6 +51,13 @@ type PendingChunk<T> = {
50
51
_response : Response ,
51
52
then ( resolve : ( T ) => mixed , reject : ( mixed ) => mixed ) : void ,
52
53
} ;
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
+ } ;
53
61
type ResolvedModelChunk < T > = {
54
62
status : 'resolved_model' ,
55
63
value : UninitializedModel ,
@@ -80,6 +88,7 @@ type ErroredChunk<T> = {
80
88
} ;
81
89
type SomeChunk < T > =
82
90
| PendingChunk < T >
91
+ | BlockedChunk < T >
83
92
| ResolvedModelChunk < T >
84
93
| ResolvedModuleChunk < T >
85
94
| InitializedChunk < T >
@@ -115,6 +124,7 @@ Chunk.prototype.then = function<T>(
115
124
resolve ( chunk . value ) ;
116
125
break ;
117
126
case PENDING :
127
+ case BLOCKED :
118
128
if ( resolve ) {
119
129
if ( chunk . value === null ) {
120
130
chunk . value = [ ] ;
@@ -159,8 +169,9 @@ function readChunk<T>(chunk: SomeChunk<T>): T {
159
169
case INITIALIZED :
160
170
return chunk . value ;
161
171
case PENDING :
172
+ case BLOCKED :
162
173
// eslint-disable-next-line no-throw-literal
163
- throw ( chunk : Thenable < T > ) ;
174
+ throw ( ( chunk : any ) : Thenable < T > ) ;
164
175
default :
165
176
throw chunk . reason ;
166
177
}
@@ -177,6 +188,11 @@ function createPendingChunk<T>(response: Response): PendingChunk<T> {
177
188
return new Chunk ( PENDING , null , null , response ) ;
178
189
}
179
190
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
+
180
196
function createErrorChunk< T > (
181
197
response: Response,
182
198
error: Error,
@@ -210,6 +226,7 @@ function wakeChunkIfInitialized<T>(
210
226
wakeChunk ( resolveListeners , chunk . value ) ;
211
227
break ;
212
228
case PENDING :
229
+ case BLOCKED :
213
230
chunk . value = resolveListeners ;
214
231
chunk . reason = rejectListeners ;
215
232
break ;
@@ -222,7 +239,7 @@ function wakeChunkIfInitialized<T>(
222
239
}
223
240
224
241
function triggerErrorOnChunk< T > (chunk: SomeChunk< T > , error: mixed): void {
225
- if ( chunk . status !== PENDING ) {
242
+ if ( chunk . status !== PENDING && chunk . status !== BLOCKED ) {
226
243
// We already resolved. We didn't expect to see this.
227
244
return ;
228
245
}
@@ -278,7 +295,7 @@ function resolveModuleChunk<T>(
278
295
chunk: SomeChunk< T > ,
279
296
value: ModuleReference< T > ,
280
297
): void {
281
- if ( chunk . status !== PENDING ) {
298
+ if ( chunk . status !== PENDING && chunk . status !== BLOCKED ) {
282
299
// We already resolved. We didn't expect to see this.
283
300
return ;
284
301
}
@@ -308,11 +325,11 @@ function initializeModelChunk<T>(chunk: ResolvedModelChunk<T>): void {
308
325
) {
309
326
initializingChunkBlockedModel . value = value ;
310
327
// 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 ;
316
333
} else {
317
334
const initializedChunk : InitializedChunk < T > = ( chunk : any ) ;
318
335
initializedChunk . status = INITIALIZED ;
@@ -348,7 +365,9 @@ export function reportGlobalError(response: Response, error: Error): void {
348
365
// If this chunk was already resolved or errored, it won't
349
366
// trigger an error but if it wasn't then we need to
350
367
// 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
+ }
352
371
} ) ;
353
372
}
354
373
@@ -433,7 +452,7 @@ function createModelResolver<T>(
433
452
parentObject [ key ] = value ;
434
453
blocked . deps -- ;
435
454
if ( blocked . deps === 0 ) {
436
- if ( chunk . status !== PENDING ) {
455
+ if ( chunk . status !== BLOCKED ) {
437
456
return ;
438
457
}
439
458
const resolveListeners = chunk . value ;
@@ -480,6 +499,7 @@ export function parseModelString(
480
499
case INITIALIZED :
481
500
return chunk . value ;
482
501
case PENDING :
502
+ case BLOCKED :
483
503
const parentChunk = initializingChunk ;
484
504
chunk . then (
485
505
createModelResolver ( parentChunk , parentObject , key ) ,
@@ -573,21 +593,28 @@ export function resolveModule(
573
593
// that we'll need them.
574
594
const promise = preloadModule ( moduleReference ) ;
575
595
if ( promise ) {
576
- let pendingChunk ;
596
+ let blockedChunk : BlockedChunk < any > ;
577
597
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 ) ;
580
602
} 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 ;
582
607
}
583
608
promise . then (
584
- ( ) => resolveModuleChunk ( pendingChunk , moduleReference ) ,
585
- error => triggerErrorOnChunk ( pendingChunk , error ) ,
609
+ ( ) => resolveModuleChunk ( blockedChunk , moduleReference ) ,
610
+ error => triggerErrorOnChunk ( blockedChunk , error ) ,
586
611
) ;
587
612
} else {
588
613
if ( ! chunk ) {
589
614
chunks . set ( id , createResolvedModuleChunk ( response , moduleReference ) ) ;
590
615
} else {
616
+ // This can't actually happen because we don't have any forward
617
+ // references to modules.
591
618
resolveModuleChunk ( chunk , moduleReference ) ;
592
619
}
593
620
}
0 commit comments