Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/compartment-mapper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"ses": "workspace:^"
},
"devDependencies": {
"@endo/env-options": "workspace:^",
"ava": "catalog:dev",
"c8": "catalog:dev",
"eslint": "catalog:dev",
Expand Down
48 changes: 22 additions & 26 deletions packages/compartment-mapper/src/archive-lite.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Provides functions to create an archive (zip file with a
/**
* Provides functions to create an archive (zip file with a
* compartment-map.json) from a partially completed compartment map (it must
* mention all packages/compartments as well as inter-compartment references
* but does not contain an entry for every module reachable from its entry
Expand Down Expand Up @@ -26,6 +27,8 @@
* In fruition of https://github.com/endojs/endo/issues/400, we will be able to
* use original source archives on XS and Node.js, but not on the web until the
* web platform makes further progress on virtual module loaers.
*
* @module
*/

/* eslint no-shadow: 0 */
Expand All @@ -36,8 +39,8 @@
* ArchiveResult,
* ArchiveWriter,
* CaptureSourceLocationHook,
* CompartmentMapDescriptor,
* HashPowers,
* PackageCompartmentMapDescriptor,
* ReadFn,
* ReadPowers,
* Sources,
Expand All @@ -58,16 +61,7 @@ import { digestCompartmentMap } from './digest.js';

const textEncoder = new TextEncoder();

const { assign, create, freeze } = Object;

/**
* @param {string} rel - a relative URL
* @param {string} abs - a fully qualified URL
* @returns {string}
*/
const resolveLocation = (rel, abs) => new URL(rel, abs).toString();

const { keys } = Object;
const { assign, create, freeze, keys } = Object;

/**
* @param {ArchiveWriter} archive
Expand All @@ -77,12 +71,10 @@ const addSourcesToArchive = async (archive, sources) => {
await null;
for (const compartment of keys(sources).sort()) {
const modules = sources[compartment];
const compartmentLocation = resolveLocation(`${compartment}/`, 'file:///');
for (const specifier of keys(modules).sort()) {
const { bytes, location } = modules[specifier];
if (location !== undefined) {
const moduleLocation = resolveLocation(location, compartmentLocation);
const path = new URL(moduleLocation).pathname.slice(1); // elide initial "/"
if ('location' in modules[specifier]) {
const { bytes, location } = modules[specifier];
const path = `${compartment}/${location}`;
if (bytes !== undefined) {
// eslint-disable-next-line no-await-in-loop
await archive.write(path, bytes);
Expand All @@ -100,16 +92,16 @@ const captureSourceLocations = async (sources, captureSourceLocation) => {
for (const compartmentName of keys(sources).sort()) {
const modules = sources[compartmentName];
for (const moduleSpecifier of keys(modules).sort()) {
const { sourceLocation } = modules[moduleSpecifier];
if (sourceLocation !== undefined) {
if ('sourceLocation' in modules[moduleSpecifier]) {
const { sourceLocation } = modules[moduleSpecifier];
captureSourceLocation(compartmentName, moduleSpecifier, sourceLocation);
}
}
}
};

/**
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {Sources} sources
* @returns {ArchiveResult}
*/
Expand All @@ -130,9 +122,11 @@ export const makeArchiveCompartmentMap = (compartmentMap, sources) => {
};
};

const noop = () => {};

/**
* @param {ReadFn | ReadPowers} powers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
* @returns {Promise<{sources: Sources, compartmentMapBytes: Uint8Array, sha512?: string}>}
*/
Expand All @@ -146,6 +140,7 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => {
policy = undefined,
sourceMapHook = undefined,
parserForLanguage: parserForLanguageOption = {},
log: _log = noop,
} = options;

const parserForLanguage = freeze(
Expand Down Expand Up @@ -179,6 +174,7 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => {
importHook: consolidatedExitModuleImportHook,
sourceMapHook,
});

// Induce importHook to record all the necessary modules to import the given module specifier.
const { compartment, attenuatorsCompartment } = link(compartmentMap, {
resolve,
Expand Down Expand Up @@ -229,7 +225,7 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => {

/**
* @param {ReadFn | ReadPowers} powers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
* @returns {Promise<{bytes: Uint8Array, sha512?: string}>}
*/
Expand All @@ -254,7 +250,7 @@ export const makeAndHashArchiveFromMap = async (

/**
* @param {ReadFn | ReadPowers} powers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
* @returns {Promise<Uint8Array>}
*/
Expand All @@ -269,7 +265,7 @@ export const makeArchiveFromMap = async (powers, compartmentMap, options) => {

/**
* @param {ReadFn | ReadPowers} powers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
* @returns {Promise<Uint8Array>}
*/
Expand All @@ -284,7 +280,7 @@ export const mapFromMap = async (powers, compartmentMap, options) => {

/**
* @param {HashPowers} powers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
* @returns {Promise<string>}
*/
Expand All @@ -302,7 +298,7 @@ export const hashFromMap = async (powers, compartmentMap, options) => {
* @param {WriteFn} write
* @param {ReadFn | ReadPowers} readPowers
* @param {string} archiveLocation
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {ArchiveLiteOptions} [options]
*/
export const writeArchiveFromMap = async (
Expand Down
7 changes: 7 additions & 0 deletions packages/compartment-mapper/src/archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* ReadPowers,
* HashPowers,
* WriteFn,
* LogFn,
* } from './types.js'
*/

Expand Down Expand Up @@ -169,6 +170,9 @@ export const mapLocation = async (powers, moduleLocation, options = {}) => {
});
};

/** @type {LogFn} */
const noop = () => {};

/**
* @param {HashPowers} powers
* @param {string} moduleLocation
Expand All @@ -191,10 +195,12 @@ export const hashLocation = async (powers, moduleLocation, options = {}) => {
workspaceLanguageForExtension,
workspaceCommonjsLanguageForExtension,
workspaceModuleLanguageForExtension,
log = noop,
...otherOptions
} = assignParserForLanguage(options);

const compartmentMap = await mapNodeModules(powers, moduleLocation, {
log,
dev,
strict,
conditions,
Expand All @@ -212,6 +218,7 @@ export const hashLocation = async (powers, moduleLocation, options = {}) => {
return hashFromMap(powers, compartmentMap, {
parserForLanguage,
policy,
log,
...otherOptions,
});
};
Expand Down
43 changes: 19 additions & 24 deletions packages/compartment-mapper/src/bundle-lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* } from 'ses'
* @import {
* BundleOptions,
* CompartmentDescriptor,
* CompartmentMapDescriptor,
* CompartmentSources,
* PackageCompartmentDescriptors,
* PackageCompartmentMapDescriptor,
* MaybeReadPowers,
* ReadFn,
* ReadPowers,
Expand Down Expand Up @@ -110,6 +110,11 @@ import { defaultParserForLanguage } from './archive-parsers.js';
import mjsSupport from './bundle-mjs.js';
import cjsSupport from './bundle-cjs.js';
import jsonSupport from './bundle-json.js';
import {
isErrorModuleSource,
isExitModuleSource,
isLocalModuleSource,
} from './guards.js';

const { quote: q } = assert;

Expand Down Expand Up @@ -144,7 +149,7 @@ null,
* The first modules are place-holders for the modules that exit
* the compartment map to the host's module system.
*
* @param {Record<string, CompartmentDescriptor>} compartmentDescriptors
* @param {PackageCompartmentDescriptors} compartmentDescriptors
* @param {Record<string, CompartmentSources>} compartmentSources
* @param {string} entryCompartmentName
* @param {string} entryModuleSpecifier
Expand Down Expand Up @@ -188,28 +193,18 @@ const sortedModules = (

const source = compartmentSources[compartmentName][moduleSpecifier];
if (source !== undefined) {
const { record, parser, deferredError, bytes, sourceDirname, exit } =
source;
if (exit !== undefined) {
return exit;
}
assert(
bytes !== undefined,
`No bytes for ${moduleSpecifier} in ${compartmentName}`,
);
assert(
parser !== undefined,
`No parser for ${moduleSpecifier} in ${compartmentName}`,
);
assert(
sourceDirname !== undefined,
`No sourceDirname for ${moduleSpecifier} in ${compartmentName}`,
);
if (deferredError) {
if (isErrorModuleSource(source)) {
throw Error(
`Cannot bundle: encountered deferredError ${deferredError}`,
`Cannot bundle: encountered deferredError ${source.deferredError}`,
);
}
if (isExitModuleSource(source)) {
return source.exit;
}
if (!isLocalModuleSource(source)) {
throw new TypeError(`Unexpected source type ${JSON.stringify(source)}`);
}
const { record, parser, bytes, sourceDirname } = source;
if (record) {
const { imports = [], reexports = [] } =
/** @type {PrecompiledStaticModuleInterface} */ (record);
Expand Down Expand Up @@ -309,7 +304,7 @@ const getBundlerKitForModule = (module, params) => {

/**
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {BundleOptions} [options]
* @returns {Promise<string>}
*/
Expand Down Expand Up @@ -651,7 +646,7 @@ ${m.bundlerKit.getFunctor()}`,

/**
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {BundleOptions} [options]
* @returns {Promise<string>}
*/
Expand Down
43 changes: 19 additions & 24 deletions packages/compartment-mapper/src/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* } from 'ses'
* @import {
* BundleOptions,
* CompartmentDescriptor,
* CompartmentMapDescriptor,
* CompartmentSources,
* PackageCompartmentDescriptors,
* PackageCompartmentMapDescriptor,
* MaybeReadPowers,
* ReadFn,
* ReadPowers,
Expand Down Expand Up @@ -112,6 +112,11 @@ import { defaultParserForLanguage } from './archive-parsers.js';
import mjsSupport from './bundle-mjs.js';
import cjsSupport from './bundle-cjs.js';
import jsonSupport from './bundle-json.js';
import {
isErrorModuleSource,
isExitModuleSource,
isLocalModuleSource,
} from './guards.js';

const textEncoder = new TextEncoder();

Expand Down Expand Up @@ -148,7 +153,7 @@ null,
* The first modules are place-holders for the modules that exit
* the compartment map to the host's module system.
*
* @param {Record<string, CompartmentDescriptor>} compartmentDescriptors
* @param {PackageCompartmentDescriptors} compartmentDescriptors
* @param {Record<string, CompartmentSources>} compartmentSources
* @param {string} entryCompartmentName
* @param {string} entryModuleSpecifier
Expand Down Expand Up @@ -192,28 +197,18 @@ const sortedModules = (

const source = compartmentSources[compartmentName][moduleSpecifier];
if (source !== undefined) {
const { record, parser, deferredError, bytes, sourceDirname, exit } =
source;
if (exit !== undefined) {
return exit;
}
assert(
bytes !== undefined,
`No bytes for ${moduleSpecifier} in ${compartmentName}`,
);
assert(
parser !== undefined,
`No parser for ${moduleSpecifier} in ${compartmentName}`,
);
assert(
sourceDirname !== undefined,
`No sourceDirname for ${moduleSpecifier} in ${compartmentName}`,
);
if (deferredError) {
if (isErrorModuleSource(source)) {
throw Error(
`Cannot bundle: encountered deferredError ${deferredError}`,
`Cannot bundle: encountered deferredError ${source.deferredError}`,
);
}
if (isExitModuleSource(source)) {
return source.exit;
}
if (!isLocalModuleSource(source)) {
throw new TypeError(`Unexpected source type ${JSON.stringify(source)}`);
}
const { record, parser, bytes, sourceDirname } = source;
if (record) {
const { imports = [], reexports = [] } =
/** @type {PrecompiledStaticModuleInterface} */ (record);
Expand Down Expand Up @@ -314,7 +309,7 @@ const getBundlerKitForModule = (module, params) => {

/**
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {BundleOptions} [options]
* @returns {Promise<string>}
*/
Expand Down Expand Up @@ -657,7 +652,7 @@ ${m.bundlerKit.getFunctor()}`,

/**
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
* @param {CompartmentMapDescriptor} compartmentMap
* @param {PackageCompartmentMapDescriptor} compartmentMap
* @param {BundleOptions} [options]
* @returns {Promise<string>}
*/
Expand Down
Loading