Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
20 changes: 15 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@ cd endo
yarn
```

Endo is a yarn workspaces repository. Running yarn in the root will install and hoist most dependencies up to the root `node_modules`.
Endo is a yarn workspaces repository. Running yarn in the root will install
and hoist most dependencies up to the root `node_modules`.

Note: running yarn `--ignore-scripts` will not complete the setup of SES.
Note: Endo uses `lerna` only for releasing. `lerna bootstrap` is unlikely to work.

## Creating a new package
# Creating a new package

Run <code>[scripts/create-package.sh](./scripts/create-package.sh) $name</code>,
then update the resulting README.md, package.json (specifically setting
`description` and [if appropriate] removing `"private": false`), index.js, and
index.test.js files.

## Rebuilding `ses`
# Code and Documentation Formatting Conventions

Changes to `ses` require a `yarn build` to be reflected in any dependency where `import 'ses';` appears. Use `yarn build` under `packages/ses` to refresh the build.
Everything else is wired up thanks to workspaces, so no need to run installs in other packages.
## Line Wrapping

- **General text**: Wrap lines at approximately 80-85 characters to maintain readability.
- **Code examples**: Follow the same line wrapping conventions as general text.
- **Long sentences**: Break long sentences across multiple lines, with each line being
approximately 80-85 characters.
- **New sentences**: Begin new sentences on fresh lines.
This ensures that changes to one sentence that require adjustments to line
wrapping do not cascade into a subsequent sentence.
This allows us to avoid expressing an opinion on one or two spaces after
periods.

# Making a Release

Expand Down
83 changes: 25 additions & 58 deletions packages/compartment-mapper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,18 @@ type ReadPowers = {
}
```

> [!NOTE]
> TODO: A future version will allow application authors to distribute their
> choices of globals and built-in modules to third-party packages within the
> application, as with [LavaMoat].
A compartment map may include a `policy` that the Compartment Mapper will then
respect at runtime to attenuate access to globals and host built-in modules and
cross-package linkage.
The policy schema follows the structure defined in
[`src/types/policy-schema.ts`](./src/types/policy-schema.ts), where each
compartment can specify:
- **`packages`**: Control over which other packages can be imported
- **`globals`**: Access to global variables and functions
- **`builtins`**: Access to built-in modules like `fs`, `crypto`, etc.
- **`defaultAttenuator`**: Default attenuation strategy for the compartment

For a working example of policies in action, see the [Policy Demo](demo/policy/README.md).

The `importLocation` function internally uses `loadLocation`.
Use `loadLocation` to defer execution or evaluate multiple times with varying
Expand Down Expand Up @@ -348,7 +356,8 @@ If no `exports` apply to the root of the compartment namespace (`"."`),
the `main` property serves as a default.

> [!NOTE]
> TODO: A future version may also respect the `imports` property.
> Future versions may also respect the `imports` property.
> See [issue #2898](https://github.com/endojs/endo/issues/2898) for more details.

> [!NOTE]
> TODO: A future version may also respect wildcard patterns in `exports` and
Expand All @@ -363,14 +372,6 @@ With the compartment mapper, just as in Node.js, a module specifier that has no
extension may refer either to the file with the `js` extension, or if that file
does not exist, to the `index.js` file in the directory with the same name.

> [!NOTE]
> TODO: The compartment mapper does not yet do anything with the `files` globs
> but a future version of the compartment mapper will collect these in archives.
> The compartment mapper should eventually provide the means for any
> compartment to access its own files using an attenuated `fs` module or
> `fetch` global, in conjunction with usable values for `import.meta.url` in
> ECMAScript modules or `__dirname` and `__filename` in CommonJS modules.

## Language Extensions

Node.js version 14 or greater treats `.mjs` files as ECMAScript modules and
Expand Down Expand Up @@ -446,11 +447,7 @@ override the extension-to-language mapping.
```

> [!NOTE]
> TODO: The compartment mapper may elect to respect some properties specified
> for import maps.

> [!NOTE]
> TODO: A future version of the compartment mapper may add support for
> Future versions of the compartment mapper may add support for
> source-to-source translation in the scope of a package or compartment.
> This would be expressed in `package.json` using a property like
> `translate` that would contain a map from file extension
Expand All @@ -465,7 +462,7 @@ override the extension-to-language mapping.
> from the production application and archived applications.

> [!NOTE]
> TODO: The compartment mapper may also add support for compartment map plugins
> Future versions of the compartment mapper may also add support for compartment map plugins
> that would recognize packages in `devDependencies` that need to introduce
> globals.
> For example, _packages_ that use JSX and a virtual DOM would be able to add a
Expand Down Expand Up @@ -586,7 +583,6 @@ type CompartmentMap = {
tags: Conditions,
entry: Entry,
compartments: Record<CompartmentName, Compartment>,
realms: Record<RealmName, Realm>, // TODO
};

// Conditions influence which modules are selected
Expand All @@ -613,9 +609,6 @@ type Compartment = {
parsers: ParserMap,
types: ModuleParserMap,
scopes: ScopeMap,
// The name of the realm to run the compartment within.
// The default is a single frozen realm that has no name.
realm?: RealmName // TODO
};

// Location is the URL relative to the compartment-map.json's
Expand All @@ -629,14 +622,11 @@ type ModuleMap = Record<InternalModuleSpecifier, Module>;
// Module describes a module in a compartment.
type Module = CompartmentModule | FileModule | ExitModule;

// CompartmentModule describes a module that isn't in the same
// compartment and how to introduce it to the compartment's
// module namespace.
// CompartmentModule describes a module that may be in the same or a different
// compartment and how to introduce it to the compartment's module namespace.
type CompartmentModule = {
// The name of the foreign compartment:
// TODO an absent compartment name may imply either
// that the module is an internal alias of the
// same compartment, or given by the user.
// When absent, defaults to the current compartment (internal alias).
compartment?: CompartmentName,
// The name of the module in the foreign compartment's
// module namespace:
Expand Down Expand Up @@ -687,6 +677,10 @@ type ExternalModuleSpecifier = string;
// The compartment mapper adds `{"json": "json"}` for good measure in both
// cases, although Node.js (as of version 0.14.5) does not support importing
// JSON modules from ESM.
// A later, experimental version permitted importing JSON, inferring the module
// format from the module specifier's extension.
// Node.js 23.1 added formal support for importing JSON but requires an
// explicit `with { type: "json" }` import attribute.
type ParserMap = Record<Extension, Parser>;

// Extension is a file extension such as "js" for "main.js" or "" for "README".
Expand Down Expand Up @@ -724,33 +718,6 @@ type ScopeMap = Record<InternalModuleSpecifier, Scope>;
type Scope = {
compartment: CompartmentName
};


// TODO everything hereafter...

// Realm describes another realm to contain one or more
// compartments.
// The default realm is frozen by lockdown with no
// powerful references.
type Realm = {
// TODO lockdown options
};

// RealmName is an arbitrary identifier for realms
// for reference from any Compartment description.
// No names are reserved; the default realm has no name.
type RealmName = string;

// ModuleParameter indicates that the module does not come from
// another compartment but must be passed expressly into the
// application by the user.
// For example, the Node.js `fs` built-in module provides
// powers that must be expressly granted to an application
// and may be attenuated or limited by the compartment mapper on behalf of the
// user.
// The string value is the name of the module to be provided
// in the application's given module map.
type ModuleParameter = string;
```

# Compartment map policy
Expand All @@ -761,9 +728,9 @@ The rules defined by policy get preserved in the compartment map and enforced in
The shape of the `policy` object is based on `policy.json` from LavaMoat. MetaMask's [LavaMoat] generates a `policy.json` file that serves the same purposes, using a tool called TOFU: _trust on first use_.

> [!NOTE]
> TODO: Endo policy support is intended to reach parity with LavaMoat's
> Endo policy support is intended to reach parity with LavaMoat's
> policy.json.
> Policy generation may be ported to Endo.
> Policy generation may be ported to Endo in future versions.

[LavaMoat]: https://github.com/LavaMoat/lavamoat
[Compartments]: ../ses/README.md#compartment
Expand Down
4 changes: 2 additions & 2 deletions packages/ocapn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

🚧 Work in progress.

An implementation of the (OCapN protocol)[https://github.com/ocapn/ocapn/].
An implementation of the [OCapN protocol](https://github.com/ocapn/ocapn/).

Includes codecs for (Syrup encoded messages)[https://github.com/ocapn/syrup/].
Includes codecs for [Syrup encoded messages](https://github.com/ocapn/syrup/).
8 changes: 4 additions & 4 deletions packages/ses/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const c = new Compartment({
globals: {
print: harden(console.log),
},
__options__: true, // temporary migration affordance
__options__: true, // required for SES shim compatibility
});

c.evaluate(`
Expand Down Expand Up @@ -305,7 +305,7 @@ const c1 = new Compartment({
source: new ModuleSource(moduleText, moduleLocation)
};
},
__options__: true, // temporary migration affordance
__options__: true, // required for SES shim compatibility
});
```

Expand All @@ -328,7 +328,7 @@ const c2 = new Compartment({
},
resolveHook,
importHook,
__options__: true, // temporary migration affordance
__options__: true, // required for SES shim compatibility
});
```

Expand Down Expand Up @@ -509,7 +509,7 @@ const compartment = new Compartment({
source: new ModuleSource(moduleText, moduleLocation),
};
},
__options__: true, // temporary migration affordance
__options__: true, // required for SES shim compatibility
});
//... | importHook | importNowHook
await compartment.import('a'); //| called | not called
Expand Down