esm: use sync loading/resolving on non-loader-hook thread · nodejs/node@3bcf86d
@@ -23,16 +23,15 @@ const {
2323} = globalThis;
24242525const {
26+ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED,
2627ERR_INTERNAL_ASSERTION,
2728ERR_INVALID_ARG_TYPE,
2829ERR_INVALID_ARG_VALUE,
2930ERR_INVALID_RETURN_PROPERTY_VALUE,
3031ERR_INVALID_RETURN_VALUE,
3132ERR_LOADER_CHAIN_INCOMPLETE,
32-ERR_METHOD_NOT_IMPLEMENTED,
3333ERR_WORKER_UNSERIALIZABLE_ERROR,
3434} = require('internal/errors').codes;
35-const { exitCodes: { kUnsettledTopLevelAwait } } = internalBinding('errors');
3635const { URLParse } = require('internal/url');
3736const { canParse: URLCanParse } = internalBinding('url');
3837const { 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 {
169169170170allowImportMetaResolve = 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 {
560558debug('wait for signal from worker');
561559AtomicsWait(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 0);
562560const 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.
566567this.#unwrapMessage(response);
@@ -647,10 +648,13 @@ class AsyncLoaderHookWorker {
647648this.#workerNotificationLastId = AtomicsLoad(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);
648649649650response = 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+652654if (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') {
655659process.exit(response.message.body);
656660}
@@ -819,6 +823,8 @@ class AsyncLoaderHooksProxiedToLoaderHookWorker {
819823820824allowImportMetaResolve = true;
821825826+isForAsyncLoaderHookWorker = false;
827+822828/**
823829 * Instantiate a module loader that uses user-provided custom loader hooks.
824830 */