Skip to content

Commit

Permalink
initialize hook PoC
Browse files Browse the repository at this point in the history
  • Loading branch information
targos committed Jun 21, 2023
1 parent 198affc commit c4f5e91
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 12 deletions.
22 changes: 17 additions & 5 deletions lib/internal/modules/esm/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ class Hooks {
* @param {string} urlOrSpecifier
* @param {string} parentURL
*/
async register(urlOrSpecifier, parentURL) {
async register(urlOrSpecifier, options) {
const {
parentURL = 'data:',
data,
} = options;
const moduleLoader = require('internal/process/esm_loader').esmLoader;

const keyedExports = await moduleLoader.import(
Expand All @@ -133,7 +137,7 @@ class Hooks {
kEmptyObject,
);

this.addCustomLoader(urlOrSpecifier, keyedExports);
this.addCustomLoader(urlOrSpecifier, keyedExports, data);
}

/**
Expand All @@ -142,13 +146,17 @@ class Hooks {
* @param {string} url Custom loader specifier
* @param {Record<string, unknown>} exports
*/
addCustomLoader(url, exports) {
addCustomLoader(url, exports, data) {
const {
initialize,
globalPreload,
resolve,
load,
} = pluckHooks(exports);

if (initialize) {
initialize(data);
}
if (globalPreload) {
ArrayPrototypePush(this.#chains.globalPreload, { fn: globalPreload, url });
}
Expand Down Expand Up @@ -577,12 +585,12 @@ class HooksProxy {
return body;
}

makeSyncRequest(method, ...args) {
makeSyncRequest(method, args, transferList) {
this.#waitForWorker();

// Pass work to the worker.
debug('post sync message to worker', { method, args });
this.#worker.postMessage({ method, args });
this.#worker.postMessage({ method, args }, transferList);

let response;
do {
Expand Down Expand Up @@ -660,12 +668,16 @@ ObjectSetPrototypeOf(HooksProxy.prototype, null);
* @returns {ExportedHooks}
*/
function pluckHooks({
initialize,
globalPreload,
resolve,
load,
}) {
const acceptedHooks = { __proto__: null };

if (initialize) {
acceptedHooks.initialize = initialize;
}
if (globalPreload) {
acceptedHooks.globalPreload = globalPreload;
}
Expand Down
10 changes: 5 additions & 5 deletions lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ class CustomizedModuleLoader extends DefaultModuleLoader {
* registered if using it package name as specifier
* @returns {{ format: string, url: URL['href'] }}
*/
register(originalSpecifier, parentURL) {
return hooksProxy.makeSyncRequest('register', originalSpecifier, parentURL);
register(originalSpecifier, options) {
return hooksProxy.makeSyncRequest('register', [originalSpecifier, options], options.transferList);
}

/**
Expand All @@ -313,7 +313,7 @@ class CustomizedModuleLoader extends DefaultModuleLoader {
* @returns {{ format: string, url: URL['href'] }}
*/
resolve(originalSpecifier, parentURL, importAssertions) {
return hooksProxy.makeSyncRequest('resolve', originalSpecifier, parentURL, importAssertions);
return hooksProxy.makeSyncRequest('resolve', [originalSpecifier, parentURL, importAssertions]);
}

async #getModuleJob(specifier, parentURL, importAssertions) {
Expand Down Expand Up @@ -404,15 +404,15 @@ function getHooksProxy() {
* register(new URL('./myLoader.js', import.meta.url));
* ```
*/
function register(specifier, parentURL = 'data:') {
function register(specifier, options = { __proto__: null }) {
// TODO: Remove this limitation in a follow-up before `register` is released publicly
if (getOptionValue('--experimental-loader').length < 1) {
throw new ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE();
}

const moduleLoader = require('internal/process/esm_loader').esmLoader;

moduleLoader.register(`${specifier}`, parentURL);
moduleLoader.register(`${specifier}`, options);
}

module.exports = {
Expand Down
4 changes: 4 additions & 0 deletions poc.loader.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function initialize({ entryPoint, port }) {
console.log('initialize loader', { entryPoint });
port.postMessage('loader initialized');
}
16 changes: 16 additions & 0 deletions poc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import module from 'node:module';

const { port1, port2 } = new MessageChannel();

module.register('./poc.loader.mjs', {
parentURL: import.meta.url,
data: {
entryPoint: process.argv[1],
port: port2
},
transferList: [port2],
});

port1.once('message', (message) => {
console.log(message);
});
2 changes: 1 addition & 1 deletion test/es-module/test-esm-loader-programmatically.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const commonArgs = [

const commonEvals = {
import: (module) => `await import(${JSON.stringify(module)});`,
register: (loader, parentURL = 'file:///') => `register(${JSON.stringify(loader)}, ${JSON.stringify(parentURL)});`,
register: (loader, parentURL = 'file:///') => `register(${JSON.stringify(loader)}, { parentURL: ${JSON.stringify(parentURL)} });`,
dynamicImport: (module) => `await import(${JSON.stringify(`data:text/javascript,${encodeURIComponent(module)}`)});`,
staticImport: (module) => `import ${JSON.stringify(`data:text/javascript,${encodeURIComponent(module)}`)};`,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { register } from 'node:module';

register('./loader-resolve-passthru.mjs', import.meta.url);
register('./loader-resolve-passthru.mjs', { parentURL: import.meta.url });

0 comments on commit c4f5e91

Please sign in to comment.