From d160c6709583e18a3d6a35630033abd1d888f7b6 Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Thu, 24 Oct 2024 14:50:08 -0700 Subject: [PATCH] feat(compartment-mapper): Collect unretained module descriptors --- packages/compartment-mapper/NEWS.md | 5 ++++ .../compartment-mapper/src/archive-lite.js | 23 +++++++++++-------- .../compartment-mapper/src/compartment-map.js | 9 +++++++- .../compartment-mapper/src/import-hook.js | 2 ++ packages/compartment-mapper/src/link.js | 3 +++ packages/compartment-mapper/src/types.js | 3 ++- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/compartment-mapper/NEWS.md b/packages/compartment-mapper/NEWS.md index 4d5d249d6a..7a2aab4488 100644 --- a/packages/compartment-mapper/NEWS.md +++ b/packages/compartment-mapper/NEWS.md @@ -1,5 +1,10 @@ User-visible changes to `@endo/compartment-mapper`: +# Next version + +- Omits unused module descriptors from `compartment-map.json` in archived + applications, potentially reducing file sizes. + # v1.3.0 (2024-10-10) - Adds support for dynamic requires in CommonJS modules. This requires specific diff --git a/packages/compartment-mapper/src/archive-lite.js b/packages/compartment-mapper/src/archive-lite.js index 5ffa0d721b..a2201fd792 100644 --- a/packages/compartment-mapper/src/archive-lite.js +++ b/packages/compartment-mapper/src/archive-lite.js @@ -148,22 +148,25 @@ const translateCompartmentMap = (compartments, sources, compartmentRenames) => { const result = create(null); for (const compartmentName of keys(compartmentRenames)) { const compartment = compartments[compartmentName]; - const { name, label, retained, policy } = compartment; - if (retained) { + const { name, label, retained: compartmentRetained, policy } = compartment; + if (compartmentRetained) { // rename module compartments /** @type {Record} */ const modules = create(null); const compartmentModules = compartment.modules; if (compartment.modules) { for (const name of keys(compartmentModules).sort()) { - const module = compartmentModules[name]; - if (module.compartment !== undefined) { - modules[name] = { - ...module, - compartment: compartmentRenames[module.compartment], - }; - } else { - modules[name] = module; + const { retained: moduleRetained, ...retainedModule } = + compartmentModules[name]; + if (moduleRetained) { + if (retainedModule.compartment !== undefined) { + modules[name] = { + ...retainedModule, + compartment: compartmentRenames[retainedModule.compartment], + }; + } else { + modules[name] = retainedModule; + } } } } diff --git a/packages/compartment-mapper/src/compartment-map.js b/packages/compartment-mapper/src/compartment-map.js index e8e61fc1ce..87b67275b4 100644 --- a/packages/compartment-mapper/src/compartment-map.js +++ b/packages/compartment-mapper/src/compartment-map.js @@ -107,7 +107,7 @@ const assertConditions = (conditions, url) => { * @param {string} url */ const assertCompartmentModule = (allegedModule, path, url) => { - const { compartment, module, ...extra } = allegedModule; + const { compartment, module, retained, ...extra } = allegedModule; assertEmptyObject( extra, `${path} must not have extra properties, got ${q({ @@ -125,6 +125,13 @@ const assertCompartmentModule = (allegedModule, path, url) => { 'string', `${path}.module must be a string, got ${q(module)} in ${q(url)}`, ); + if (retained !== undefined) { + assert.typeof( + retained, + 'boolean', + `${path}.retained must be a boolean, got ${q(retained)} in ${q(url)}`, + ); + } }; /** diff --git a/packages/compartment-mapper/src/import-hook.js b/packages/compartment-mapper/src/import-hook.js index b62c5ec634..cbc13e647b 100644 --- a/packages/compartment-mapper/src/import-hook.js +++ b/packages/compartment-mapper/src/import-hook.js @@ -269,6 +269,7 @@ function* chooseModuleDescriptor( for (const candidateSpecifier of candidates) { const candidateModuleDescriptor = moduleDescriptors[candidateSpecifier]; if (candidateModuleDescriptor !== undefined) { + candidateModuleDescriptor.retained = true; const { compartment: candidateCompartmentName = packageLocation } = candidateModuleDescriptor; const candidateCompartment = compartments[candidateCompartmentName]; @@ -339,6 +340,7 @@ function* chooseModuleDescriptor( // module specifier than the requested one. if (candidateSpecifier !== moduleSpecifier) { moduleDescriptors[moduleSpecifier] = { + retained: true, module: candidateSpecifier, compartment: packageLocation, }; diff --git a/packages/compartment-mapper/src/link.js b/packages/compartment-mapper/src/link.js index d099f9adbb..ef691f864e 100644 --- a/packages/compartment-mapper/src/link.js +++ b/packages/compartment-mapper/src/link.js @@ -112,6 +112,8 @@ const makeModuleMapHook = ( const moduleDescriptor = moduleDescriptors[moduleSpecifier]; if (moduleDescriptor !== undefined) { + moduleDescriptor.retained = true; + // "foreignCompartmentName" refers to the compartment which // may differ from the current compartment const { @@ -193,6 +195,7 @@ const makeModuleMapHook = ( // a moduleMapHook when we assemble compartments from the resulting // archive. moduleDescriptors[moduleSpecifier] = { + retained: true, compartment: foreignCompartmentName, module: foreignModuleSpecifier, }; diff --git a/packages/compartment-mapper/src/types.js b/packages/compartment-mapper/src/types.js index bdd3e4fc78..e5755a2aaa 100644 --- a/packages/compartment-mapper/src/types.js +++ b/packages/compartment-mapper/src/types.js @@ -61,13 +61,14 @@ export {}; * `package.json`, there is a corresponding module descriptor. * * @typedef {object} ModuleDescriptor - * @property {string=} [compartment] + * @property {string} [compartment] * @property {string} [module] * @property {string} [location] * @property {Language} [parser] * @property {string} [sha512] in base 16, hex * @property {string} [exit] * @property {string} [deferredError] + * @property {boolean} [retained] */ /**