@@ -243,19 +243,27 @@ page.on("console", async e => {
243
243
}
244
244
}
245
245
246
- if ( isDebug ) {
247
- console . error ( e . text ( ) ) ;
248
- } else if ( level === "error" ) {
249
- const text = await Promise . all (
250
- e . args ( ) . map ( async a => {
251
- try {
246
+ async function getText ( ) {
247
+ try {
248
+ return await Promise . all (
249
+ e . args ( ) . map ( async a => {
252
250
return await maybeGetError ( a ) || await a . jsonValue ( ) ;
253
- } catch ( e ) {
254
- return a . toString ( ) ;
255
- }
256
- } )
257
- ) . then ( a => a . join ( " " ) . trim ( ) ) ;
251
+ } )
252
+ ) . then ( a => a . join ( " " ) . trim ( ) ) ;
253
+ } catch {
254
+ return e . text ( ) ;
255
+ }
256
+ }
257
+
258
+ if ( isDebug ) {
259
+ const text = await getText ( ) ;
258
260
261
+ console . error ( text ) ;
262
+ if ( text . includes ( "A fatal error occurred:" ) ) {
263
+ process . exit ( 1 ) ;
264
+ }
265
+ } else if ( level === "error" ) {
266
+ const text = await getText ( ) ;
259
267
260
268
if ( text . length && ! text . startsWith ( "Failed to load resource: the server responded with a status of" ) && ! text . includes ( "Webpack" ) ) {
261
269
console . error ( "[Unexpected Error]" , text ) ;
@@ -322,22 +330,31 @@ async function runtime(token: string) {
322
330
323
331
const validChunks = new Set < string > ( ) ;
324
332
const invalidChunks = new Set < string > ( ) ;
333
+ const deferredRequires = new Set < string > ( ) ;
325
334
326
335
let chunksSearchingResolve : ( value : void | PromiseLike < void > ) => void ;
327
336
const chunksSearchingDone = new Promise < void > ( r => chunksSearchingResolve = r ) ;
328
337
329
338
// True if resolved, false otherwise
330
339
const chunksSearchPromises = [ ] as Array < ( ) => boolean > ;
331
- const lazyChunkRegex = canonicalizeMatch ( / P r o m i s e \. a l l \( ( \[ \i \. \i \( " . + ? " \) . + ? \] ) \) . t h e n \( \i \. b i n d \( \i , " ( . + ? ) " \) \) / g ) ;
332
- const chunkIdsRegex = canonicalizeMatch ( / \( " ( . + ? ) " \) / g) ;
340
+
341
+ const LazyChunkRegex = canonicalizeMatch ( / (?: P r o m i s e \. a l l \( \[ ( \i \. \i \( " [ ^ ) ] + ? " \) [ ^ \] ] + ? ) \] \) | ( \i \. \i \( " [ ^ ) ] + ? " \) ) ) \. t h e n \( \i \. b i n d \( \i , " ( [ ^ ) ] + ? ) " \) \) / g) ;
333
342
334
343
async function searchAndLoadLazyChunks ( factoryCode : string ) {
335
- const lazyChunks = factoryCode . matchAll ( lazyChunkRegex ) ;
344
+ const lazyChunks = factoryCode . matchAll ( LazyChunkRegex ) ;
336
345
const validChunkGroups = new Set < [ chunkIds : string [ ] , entryPoint : string ] > ( ) ;
337
346
338
- await Promise . all ( Array . from ( lazyChunks ) . map ( async ( [ , rawChunkIds , entryPoint ] ) => {
339
- const chunkIds = Array . from ( rawChunkIds . matchAll ( chunkIdsRegex ) ) . map ( m => m [ 1 ] ) ;
340
- if ( chunkIds . length === 0 ) return ;
347
+ // Workaround for a chunk that depends on the ChannelMessage component but may be be force loaded before
348
+ // the chunk containing the component
349
+ const shouldForceDefer = factoryCode . includes ( ".Messages.GUILD_FEED_UNFEATURE_BUTTON_TEXT" ) ;
350
+
351
+ await Promise . all ( Array . from ( lazyChunks ) . map ( async ( [ , rawChunkIdsArray , rawChunkIdsSingle , entryPoint ] ) => {
352
+ const rawChunkIds = rawChunkIdsArray ?? rawChunkIdsSingle ;
353
+ const chunkIds = rawChunkIds ? Array . from ( rawChunkIds . matchAll ( Vencord . Webpack . ChunkIdsRegex ) ) . map ( m => m [ 1 ] ) : [ ] ;
354
+
355
+ if ( chunkIds . length === 0 ) {
356
+ return ;
357
+ }
341
358
342
359
let invalidChunkGroup = false ;
343
360
@@ -373,6 +390,11 @@ async function runtime(token: string) {
373
390
// Requires the entry points for all valid chunk groups
374
391
for ( const [ , entryPoint ] of validChunkGroups ) {
375
392
try {
393
+ if ( shouldForceDefer ) {
394
+ deferredRequires . add ( entryPoint ) ;
395
+ continue ;
396
+ }
397
+
376
398
if ( wreq . m [ entryPoint ] ) wreq ( entryPoint as any ) ;
377
399
} catch ( err ) {
378
400
console . error ( err ) ;
@@ -435,6 +457,11 @@ async function runtime(token: string) {
435
457
436
458
await chunksSearchingDone ;
437
459
460
+ // Require deferred entry points
461
+ for ( const deferredRequire of deferredRequires ) {
462
+ wreq ! ( deferredRequire as any ) ;
463
+ }
464
+
438
465
// All chunks Discord has mapped to asset files, even if they are not used anymore
439
466
const allChunks = [ ] as string [ ] ;
440
467
@@ -514,7 +541,6 @@ async function runtime(token: string) {
514
541
setTimeout ( ( ) => console . log ( "[PUPPETEER_TEST_DONE_SIGNAL]" ) , 1000 ) ;
515
542
} catch ( e ) {
516
543
console . log ( "[PUP_DEBUG]" , "A fatal error occurred:" , e ) ;
517
- process . exit ( 1 ) ;
518
544
}
519
545
}
520
546
0 commit comments