@@ -9,8 +9,22 @@ const globalCache = new NodeCache({ stdTTL: 3600, checkperiod: 600 });
99const  MAX_RESOURCE_SIZE  =  15  *  ( 1024  **  2 ) ;  // 15MB 
1010var  ALLOWED_RESOURCES  =  [ 'document' ,  'stylesheet' ,  'image' ,  'media' ,  'font' ,  'other' ] ; 
1111const  ALLOWED_STATUSES  =  [ 200 ,  201 ] ; 
12- const  REQUEST_TIMEOUT  =  1800000 ; 
12+ const  REQUEST_TIMEOUT  =  180000 ; 
1313const  MIN_VIEWPORT_HEIGHT  =  1080 ; 
14+ const  MAX_WAIT_FOR_REQUEST_CALL  =  30000 ; 
15+ 
16+ const  normalizeSameSite  =  ( value )  =>  { 
17+     if  ( ! value )  return  'Lax' ; 
18+     
19+     const  normalized  =  value . trim ( ) . toLowerCase ( ) ; 
20+     const  mapping  =  { 
21+         'lax' : 'Lax' , 
22+         'strict' : 'Strict' , 
23+         'none' : 'None' 
24+     } ; 
25+     
26+     return  mapping [ normalized ]  ||  value ; 
27+ } ; 
1428
1529export  async  function  prepareSnapshot ( snapshot : Snapshot ,  ctx : Context ) : Promise < Record < string ,  any > >  { 
1630    let  processedOptions : Record < string ,  any >  =  { } ; 
@@ -257,11 +271,11 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
257271                return  false ; 
258272            } 
259273
260-             if  ( cookie . sameSite  &&  ! [ 'Strict' ,  'Lax' ,  'None' ] . includes ( cookie . sameSite ) )  { 
274+             const  sameSiteValue  =  normalizeSameSite ( cookie . sameSite ) ; 
275+             if  ( ! [ 'Strict' ,  'Lax' ,  'None' ] . includes ( sameSiteValue ) )  { 
261276                ctx . log . debug ( `Skipping invalid custom cookie: invalid sameSite value '${ cookie . sameSite }  '` ) ; 
262277                return  false ; 
263278            } 
264-             
265279            return  true ; 
266280        } ) . map ( cookie  =>  ( { 
267281            name : cookie . name , 
@@ -270,7 +284,7 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
270284            path : cookie . path  ||  '/' , 
271285            httpOnly : cookie . httpOnly  ||  false , 
272286            secure : cookie . secure  ||  false , 
273-             sameSite : cookie . sameSite   ||   'Lax' 
287+             sameSite : normalizeSameSite ( cookie . sameSite ) 
274288        } ) ) ; 
275289
276290        if  ( validCustomCookies . length  >  0 )  { 
@@ -299,6 +313,8 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
299313        } 
300314    } 
301315
316+     const  pendingRequests  =  new  Set < string > ( ) ; 
317+ 
302318    // Use route to intercept network requests and discover resources 
303319    await  page . route ( '**/*' ,  async  ( route ,  request )  =>  { 
304320        const  requestUrl  =  request . url ( ) 
@@ -357,8 +373,14 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
357373                body  =  globalCache . get ( requestUrl ) . body ; 
358374            }  else  { 
359375                ctx . log . debug ( `Resource not found in cache or global cache ${ requestUrl }   fetching from server` ) ; 
376+                 if ( ctx . build . checkPendingRequests ) { 
377+                     pendingRequests . add ( requestUrl ) ; 
378+                 } 
360379                response  =  await  page . request . fetch ( request ,  requestOptions ) ; 
361380                body  =  await  response . body ( ) ; 
381+                 if ( ctx . build . checkPendingRequests ) { 
382+                     pendingRequests . delete ( requestUrl ) ; 
383+                 } 
362384            } 
363385
364386            // handle response 
@@ -386,15 +408,26 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
386408
387409                let  responseOfRetry ,  bodyOfRetry 
388410                ctx . log . debug ( `Resource had a disallowed status ${ requestUrl }   fetching from server again` ) ; 
411+                 if ( ctx . build . checkPendingRequests ) { 
412+                     pendingRequests . add ( requestUrl ) ; 
413+                 } 
389414                responseOfRetry  =  await  page . request . fetch ( request ,  requestOptions ) ; 
390415                bodyOfRetry  =  await  responseOfRetry . body ( ) ; 
391- 
416+                 if ( ctx . build . checkPendingRequests ) { 
417+                     pendingRequests . delete ( requestUrl ) ; 
418+                 } 
392419                if  ( responseOfRetry  &&  responseOfRetry . status ( )  &&  ALLOWED_STATUSES . includes ( responseOfRetry . status ( ) ) )  { 
393420                    ctx . log . debug ( `Handling request after retry ${ requestUrl }  \n - content-type ${ responseOfRetry . headers ( ) [ 'content-type' ] }  ` ) ; 
394421                    cache [ requestUrl ]  =  { 
395422                        body : bodyOfRetry . toString ( 'base64' ) , 
396423                        type : responseOfRetry . headers ( ) [ 'content-type' ] 
397424                    } 
425+                     if  ( ctx . config . useGlobalCache )  { 
426+                         globalCache . set ( requestUrl ,  { 
427+                             body : bodyOfRetry . toString ( 'base64' ) , 
428+                             type : responseOfRetry . headers ( ) [ 'content-type' ] 
429+                         } ) ; 
430+                     } 
398431                    route . fulfill ( { 
399432                        status : responseOfRetry . status ( ) , 
400433                        headers : responseOfRetry . headers ( ) , 
@@ -445,6 +478,7 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
445478                } 
446479            } 
447480
481+ 
448482            // Continue the request with the fetched response 
449483            route . fulfill ( { 
450484                status : response . status ( ) , 
@@ -650,6 +684,7 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
650684        }  catch  ( error )  { 
651685            ctx . log . debug ( `Network idle failed due to ${ error }  ` ) ; 
652686        } 
687+         
653688
654689
655690        if  ( ctx . config . allowedAssets  &&  ctx . config . allowedAssets . length )  { 
@@ -839,6 +874,28 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
839874        ctx . log . debug ( `Processed options: ${ JSON . stringify ( processedOptions ) }  ` ) ; 
840875    } 
841876
877+     // Wait for pending requests to complete 
878+     const  checkPending  =  async  ( )  =>  { 
879+         let  startTime  =  Date . now ( ) ; 
880+         ctx . log . debug ( `${ pendingRequests . size }   Pending requests before wait for ${ snapshot . name }  : ${ Array . from ( pendingRequests ) }  ` ) ; 
881+         while  ( pendingRequests . size  >  0 )  { 
882+           const  elapsedTime  =  Date . now ( )  -  startTime ; 
883+           if  ( elapsedTime  >=  MAX_WAIT_FOR_REQUEST_CALL )  { 
884+             ctx . log . debug ( `Timeout reached (${ MAX_WAIT_FOR_REQUEST_CALL / 1000 }  s). Stopping wait for pending requests.` ) ; 
885+             ctx . log . debug ( `${ pendingRequests . size }   Pending requests after wait for ${ snapshot . name }  : ${ Array . from ( pendingRequests ) }  ` ) ; 
886+             break ; 
887+           } 
888+           await  new  Promise ( resolve  =>  setTimeout ( resolve ,  1000 ) ) ;  
889+         } 
890+         if ( pendingRequests . size  ===  0 )  { 
891+             ctx . log . debug ( `No pending requests for ${ snapshot . name }  .` ) ; 
892+         } 
893+       } ; 
894+ 
895+       if  ( ctx . build . checkPendingRequests )  { 
896+         await  checkPending ( ) ; 
897+       } 
898+ 
842899
843900    let  hasBrowserErrors  =  false ; 
844901    for  ( let  browser  in  discoveryErrors . browsers )  { 
0 commit comments