11'use strict' ;
22
33const {
4+ ArrayPrototypeFilter,
5+ ArrayPrototypeMap,
46 ArrayPrototypePush,
57 ArrayPrototypePushApply,
8+ ArrayPrototypeReduce,
69 AtomicsLoad,
710 AtomicsWait,
811 AtomicsWaitAsync,
@@ -35,7 +38,7 @@ const {
3538const { exitCodes : { kUnsettledTopLevelAwait } } = internalBinding ( 'errors' ) ;
3639const { URL } = require ( 'internal/url' ) ;
3740const { canParse : URLCanParse } = internalBinding ( 'url' ) ;
38- const { receiveMessageOnPort, isMainThread } = require ( 'worker_threads' ) ;
41+ const { receiveMessageOnPort } = require ( 'worker_threads' ) ;
3942const {
4043 isAnyArrayBuffer,
4144 isArrayBufferView,
@@ -164,6 +167,18 @@ class Hooks {
164167 * @returns {any | Promise<any> } User data, ignored unless it's a promise, in which case it will be awaited.
165168 */
166169 addCustomLoader ( url , exports , data ) {
170+ const alreadyKnown = ArrayPrototypeReduce (
171+ ArrayPrototypeMap ( [ 'initialize' , 'resolve' , 'load' ] , ( hookName ) => {
172+ if ( this . #chains[ hookName ] ) {
173+ const res2 = ArrayPrototypeFilter ( this . #chains[ hookName ] , ( el ) => el . url === url ) ;
174+ return res2 . length ;
175+ }
176+ } ) , ( acc , val ) => acc || ( val === 1 ) , false ) ;
177+
178+ if ( alreadyKnown ) {
179+ return undefined ;
180+ }
181+
167182 const {
168183 initialize,
169184 resolve,
@@ -499,13 +514,14 @@ class HooksProxy {
499514 #numberOfPendingAsyncResponses = 0 ;
500515
501516 #isReady = false ;
517+ #isWorkerOwner = false ;
502518
503519 constructor ( ) {
504- const { InternalWorker, hooksPort } = require ( 'internal/worker' ) ;
520+ const { InternalWorker, hooksPort, hasHooksThread } = require ( 'internal/worker' ) ;
505521 const lock = new SharedArrayBuffer ( SHARED_MEMORY_BYTE_LENGTH ) ;
506522 this . #lock = new Int32Array ( lock ) ;
507523
508- if ( isMainThread ) {
524+ if ( ! hasHooksThread ( ) ) {
509525 // Main thread is the only one that creates the internal single hooks worker
510526 this . #worker = new InternalWorker ( loaderWorkerId , {
511527 stderr : false ,
@@ -518,6 +534,7 @@ class HooksProxy {
518534 } ) ;
519535 this . #worker. unref ( ) ; // ! Allows the process to eventually exit.
520536 this . #worker. on ( 'exit' , process . exit ) ;
537+ this . #isWorkerOwner = true ;
521538 this . #portToHooksThread = this . #worker;
522539 } else {
523540 this . #portToHooksThread = hooksPort ;
@@ -529,7 +546,7 @@ class HooksProxy {
529546 // has an InternalWorker. That was the Hooks instance created for the main thread.
530547 // It means for all Hooks instances that are not on the main thread => they are ready because they
531548 // delegate to the single InternalWorker anyway.
532- if ( ! isMainThread ) {
549+ if ( ! this . #isWorkerOwner ) {
533550 return ;
534551 }
535552
0 commit comments