◐ Shell
clean mode source ↗

esm: use sync loading/resolving on non-loader-hook thread · nodejs/node@3bcf86d

@@ -23,16 +23,15 @@ const {

2323

} = globalThis;

24242525

const {

26+

ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED,

2627

ERR_INTERNAL_ASSERTION,

2728

ERR_INVALID_ARG_TYPE,

2829

ERR_INVALID_ARG_VALUE,

2930

ERR_INVALID_RETURN_PROPERTY_VALUE,

3031

ERR_INVALID_RETURN_VALUE,

3132

ERR_LOADER_CHAIN_INCOMPLETE,

32-

ERR_METHOD_NOT_IMPLEMENTED,

3333

ERR_WORKER_UNSERIALIZABLE_ERROR,

3434

} = require('internal/errors').codes;

35-

const { exitCodes: { kUnsettledTopLevelAwait } } = internalBinding('errors');

3635

const { URLParse } = require('internal/url');

3736

const { canParse: URLCanParse } = internalBinding('url');

3837

const { receiveMessageOnPort } = require('worker_threads');

@@ -117,15 +116,16 @@ function defineImportAssertionAlias(context) {

117116

* via `ModuleLoader.#setAsyncLoaderHooks()`.

118117

* @typedef {object} AsyncLoaderHooks

119118

* @property {boolean} allowImportMetaResolve Whether to allow the use of `import.meta.resolve`.

119+

* @property {boolean} isForAsyncLoaderHookWorker Whether the instance is running on the loader hook worker thread.

120120

* @property {(url: string, context: object, defaultLoad: Function) => Promise<LoadResult>} load

121121

* Calling the asynchronous `load` hook asynchronously.

122-

* @property {(url: string, context: object, defaultLoad: Function) => LoadResult} loadSync

122+

* @property {(url: string, context: object, defaultLoad: Function) => LoadResult} [loadSync]

123123

* Calling the asynchronous `load` hook synchronously.

124124

* @property {(originalSpecifier: string, parentURL: string,

125125

* importAttributes: Record<string, string>) => Promise<ResolveResult>} resolve

126126

* Calling the asynchronous `resolve` hook asynchronously.

127127

* @property {(originalSpecifier: string, parentURL: string,

128-

* importAttributes: Record<string, string>) => ResolveResult} resolveSync

128+

* importAttributes: Record<string, string>) => ResolveResult} [resolveSync]

129129

* Calling the asynchronous `resolve` hook synchronously.

130130

* @property {(specifier: string, parentURL: string) => any} register Register asynchronous loader hooks

131131

* @property {() => void} waitForLoaderHookInitialization Force loading of hooks.

@@ -169,6 +169,8 @@ class AsyncLoaderHooksOnLoaderHookWorker {

169169170170

allowImportMetaResolve = false;

171171172+

isForAsyncLoaderHookWorker = true;

173+172174

/**

173175

* Import and register custom/user-defined module loader hook(s).

174176

* @param {string} urlOrSpecifier

@@ -350,10 +352,6 @@ class AsyncLoaderHooksOnLoaderHookWorker {

350352

};

351353

}

352354353-

resolveSync(_originalSpecifier, _parentURL, _importAttributes) {

354-

throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()');

355-

}

356-357355

/**

358356

* Provide source that is understood by one of Node's translators.

359357

*

@@ -560,7 +558,10 @@ class AsyncLoaderHookWorker {

560558

debug('wait for signal from worker');

561559

AtomicsWait(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 0);

562560

const response = this.#worker.receiveMessageSync();

563-

if (response == null || response.message.status === 'exit') { return; }

561+

if (response == null) { return; }

562+

if (response.message.status === 'exit') {

563+

process.exit(response.message.body);

564+

}

564565565566

// ! This line catches initialization errors in the worker thread.

566567

this.#unwrapMessage(response);

@@ -647,10 +648,13 @@ class AsyncLoaderHookWorker {

647648

this.#workerNotificationLastId = AtomicsLoad(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);

648649649650

response = this.#worker.receiveMessageSync();

651+

debug('got sync message from worker', { method, args, response });

650652

} while (response == null);

651-

debug('got sync response from worker', { method, args });

653+652654

if (response.message.status === 'never-settle') {

653-

process.exit(kUnsettledTopLevelAwait);

655+

const error = new ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED();

656+

error.details = { method, args };

657+

throw error;

654658

} else if (response.message.status === 'exit') {

655659

process.exit(response.message.body);

656660

}

@@ -819,6 +823,8 @@ class AsyncLoaderHooksProxiedToLoaderHookWorker {

819823820824

allowImportMetaResolve = true;

821825826+

isForAsyncLoaderHookWorker = false;

827+822828

/**

823829

* Instantiate a module loader that uses user-provided custom loader hooks.

824830

*/