Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: endojs/endo
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6b9805df139f12f593fa476f487e90b165219b03
Choose a base ref
..
head repository: endojs/endo
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bf80971d5aac5b0d13e78265d3cdfb41870b9407
Choose a head ref
Showing with 875 additions and 941 deletions.
  1. +35 −0 .github/workflows/ci.yml
  2. +0 −1 package.json
  3. +10 −0 packages/bundle-source/NEWS.md
  4. +86 −13 packages/bundle-source/README.md
  5. +1 −1 packages/bundle-source/demo/dir1/index.js
  6. +1 −1 packages/bundle-source/demo/dir1/sub/{more.js → more.cjs}
  7. 0 packages/bundle-source/demo/dir1/sub/{things.js → things.cjs}
  8. +5 −1 packages/bundle-source/demo/external-fs.js
  9. +1 −5 packages/bundle-source/package.json
  10. +3 −21 packages/bundle-source/src/bundle-source.js
  11. +0 −297 packages/bundle-source/src/nested-evaluate-and-get-exports.js
  12. +36 −5 packages/bundle-source/src/script.js
  13. +4 −3 packages/bundle-source/test/_sanity.js
  14. +2 −2 packages/bundle-source/test/comment.test.js
  15. +0 −4 packages/bundle-source/test/explicit.test.js
  16. +6 −2 packages/bundle-source/test/external-fs.test.js
  17. +2 −0 packages/compartment-mapper/src/bundle.js
  18. +8 −0 packages/evasive-transform/NEWS.md
  19. +5 −9 packages/evasive-transform/package.json
  20. +23 −9 packages/evasive-transform/src/generate.js
  21. +5 −25 packages/evasive-transform/src/index.js
  22. +0 −80 packages/evasive-transform/src/location-unmapper.js
  23. +6 −2 packages/evasive-transform/src/parse-ast.js
  24. +8 −43 packages/evasive-transform/src/transform-ast.js
  25. +2 −10 packages/evasive-transform/src/transform-comment.js
  26. +0 −43 packages/evasive-transform/test/_rebuild-fixtures.js
  27. +0 −2 packages/evasive-transform/test/evade-censor.test.js
  28. +0 −51 packages/evasive-transform/test/location-unmapper.test.js
  29. +88 −17 packages/evasive-transform/test/snapshots/evade-censor.test.js.md
  30. BIN packages/evasive-transform/test/snapshots/evade-censor.test.js.snap
  31. +0 −3 packages/evasive-transform/tsconfig.json
  32. +4 −4 packages/module-source/package.json
  33. 0 packages/module-source/src/{babelPlugin.js → babel-plugin.js}
  34. +7 −15 packages/module-source/src/transform-analyze.js
  35. +19 −10 packages/module-source/src/{transformSource.js → transform-source.js}
  36. +2 −2 packages/module-source/test/_benchmark-babel-plugin.js
  37. +11 −0 packages/module-source/test/fixtures/format-preserved.txt
  38. +10 −0 packages/module-source/test/fixtures/preserve-format.js
  39. +1 −1 packages/module-source/test/fixtures/small.js
  40. +20 −0 packages/module-source/test/preserve-format.test.js
  41. +16 −1 packages/ses/package.json
  42. +45 −18 packages/ses/scripts/bundle.js
  43. +55 −0 packages/ses/scripts/hermes-test.sh
  44. +97 −0 packages/ses/scripts/hermes-transforms.js
  45. +40 −0 packages/ses/src/commons.js
  46. +4 −2 packages/ses/src/compartment.js
  47. +23 −18 packages/ses/src/get-anonymous-intrinsics.js
  48. +9 −5 packages/ses/src/tame-function-constructors.js
  49. +12 −0 packages/ses/test/_hermes-smoke.js
  50. +2 −2 scripts/all-versions.sh
  51. +2 −2 scripts/set-versions.sh
  52. +159 −211 yarn.lock
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -216,6 +216,41 @@ jobs:
- name: Run yarn test262
run: exit 0 # TODO remove test262 from required tests for CI

test-hermes:
name: test-hermes

# begin macro

runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]

steps:
- name: Checkout
uses: actions/checkout@v4

# without this, setup-node errors on mismatched yarn versions
- run: corepack enable

- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: yarn

- name: Install dependencies
run: yarn install --immutable

# end macro

- name: Run yarn build
run: yarn build

- name: Run SES/Hermes smoke test
run: yarn test:hermes

viable-release:
name: viable-release

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -54,7 +54,6 @@
"atLeast": 0
},
"resolutions": {
"@babel/types": "7.24.0",
"@lerna/version@npm:5.6.2": "patch:@lerna/version@npm%3A5.6.2#~/.yarn/patches/@lerna-version-npm-5.6.2-ce2d9cb2f5.patch",
"@lerna/conventional-commits@npm:5.6.2": "patch:@lerna/conventional-commits@npm%3A5.6.2#~/.yarn/patches/@lerna-conventional-commits-npm-5.6.2-a373ba4bc0.patch"
}
10 changes: 10 additions & 0 deletions packages/bundle-source/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
User-visible changes to `@endo/bundle-source`:

# Next release

- Replaces the implementation for the `nestedEvaluate` and `getExport`
formats with one based on Endo's Compartment Mapper instead of Rollup,
in order to obviate the need to reconcile source map transforms between
Rollup and the underlying Babel generator.
As a consequence, we no longer generate a source map for the bundle, but
Babel ensures that we preserve line and column numbers between the original
source and the bundled source.

# v3.5.0 (2024-11-13)

- Adds support for TypeScript type erasure using
99 changes: 86 additions & 13 deletions packages/bundle-source/README.md
Original file line number Diff line number Diff line change
@@ -121,20 +121,32 @@ not exist.
## getExport moduleFormat

The most primitive `moduleFormat` is the `"getExport"` format.
It generates source like:
It generates a script where the completion value (last expression evaluated)
is a function that accepts an optional `sourceUrlPrefix`.

```js
function getExport() {
let exports = {};
const module = { exports };
// CommonJS source translated from the inputs.
...
return module.exports;
}
cosnt { source } = await bundleSource('program.js', { format: 'getExport' });
const exports = eval(source)();
```

To evaluate it and obtain the resulting module namespace, you need to endow
a `require` function to resolve external imports.
A bundle in `getExport` format can import host modules through a
lexically-scoped CommonJS `require` function.
One can be endowed using a Hardened JavaScript `Compartment`.

```js
const compartment = new Compartment({
globals: { require },
__options__: true, // until SES and XS implementations converge
});
const exports = compartment.evaluate(source)();
```
> [!WARNING]
> The `getExport` format was previously implemented using
> [Rollup](https://rollupjs.org/) and is implemented with
> `@endo/compartment-mapper/functor.js` starting with version 4 of
> `@endo/bundle-source`.
> See `nestedEvaluate` below for compatibility caveats.
## nestedEvaluate moduleFormat
@@ -145,9 +157,70 @@ to evaluate submodules in the same context as the parent function.
The advantage of this format is that it helps preserve the filenames within
the bundle in the event of any stack traces.
Also, the toplevel `getExport(filePrefix = "/bundled-source")` accepts an
optional `filePrefix` argument (which is prepended to relative paths for the
bundled files) in order to help give context to stack traces.
The completion value of a `nestedEvaluate` bundle is a function that accepts
the `sourceUrlPrefix` for every module in the bundle, which will appear in stack
traces and assist debuggers to find a matching source file.
```js
cosnt { source } = await bundleSource('program.js', { format: 'nestedEvaluate' });
const compartment = new Compartment({
globals: {
require,
nestedEvaluate: source => compartment.evaluate(source),
},
__options__: true, // until SES and XS implementations converge
});
const exports = compartment.evaluate(source)('bundled-sources/.../');
```
In the absence of a `nextedEvaluate` function in lexical scope, the bundle will
use the `eval` function in lexical scope.
> [!WARNING]
> The `nestedEvaluate` format was previously implemented using
> [Rollup](https://rollupjs.org/) and is implemented with
> `@endo/compartment-mapper/functor.js` starting with version 4 of
> `@endo/bundle-source`.
> Their behaviors are not identical.
>
> 1. Version 3 used different heuristics than Node.js 18 for inferring whether
> a module was in CommonJS format or ESM format. Version 4 does not guess,
> but relies on the `"type": "module"` directive in `package.json` to indicate
> that a `.js` extension implies ESM format, or respects the explicit `.cjs`
> and `.mjs` extensions.
> 2. Version 3 supports [live
> bindings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#imported_values_can_only_be_modified_by_the_exporter)
> and Version 4 does not.
> 3. Version 3 can import any package that is discoverable by walking parent directories
> until the dependency or devDependeny is found in a `node_modules` directory.
> Version 4 requires that the dependent package explicitly note the dependency
> in `package.json`.
> 4. Version 3 and 4 generate different text.
> Any treatment of that text that is sensitive to the exact shape of the
> text is fragile and may break even between minor and patch versions.
> 5. Version 4 makes flags already supported by `endoZipBase64` format
> universal to all formats, including `dev`, `elideComments`,
> `noTransforms`, and `conditions`.
## endoScript moduleFormat
The `ses` shim uses the `endoScript` format to generate its distribution bundles,
suitable for injecting in a web page with a `<script>` tag.
For this format, extract the `source` from the generated JSON envelope and place
it in a file you embed in a web page, an Agoric
[Core Eval](https://docs.agoric.com/guides/coreeval/) script, or evaluate
anywhere that accepts scripts.
```js
const { source } = await bundleSource('program.js', { format: 'endoScript' });
const compartment = new Compartment();
compartment.evaluate(source);
```
Unlike `getExport` and `nestedEvaluate`, the `dev` option to `bundleSource` is
required for any bundle that imports `devDependencies`.
The `endoScript` format does not support importing host modules with CommonJS
`require`.
## endoZipBase64 moduleFormat
2 changes: 1 addition & 1 deletion packages/bundle-source/demo/dir1/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { encourage, makeError } from './encourage.js';
import more from './sub/more.js';
import more from './sub/more.cjs';

export default function makeEncourager() {
return harden({
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global exports require */
const things = require('./things.js');
const things = require('./things.cjs');

exports.more = `have more ${things.description}`;
6 changes: 5 additions & 1 deletion packages/bundle-source/demo/external-fs.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import 'fs';
import * as fs from 'fs';
import { readFileSync } from 'fs';

assert(fs[Symbol.toStringTag] === 'Module');
assert(typeof readFileSync === 'function');
6 changes: 1 addition & 5 deletions packages/bundle-source/package.json
Original file line number Diff line number Diff line change
@@ -31,11 +31,6 @@
"@endo/init": "workspace:^",
"@endo/promise-kit": "workspace:^",
"@endo/where": "workspace:^",
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"acorn": "^8.2.4",
"rollup": "^2.79.1",
"ts-blank-space": "^0.4.1"
},
"devDependencies": {
@@ -45,6 +40,7 @@
"ava": "^6.1.3",
"c8": "^7.14.0",
"eslint": "^8.57.0",
"ses": "workspace:^",
"typescript": "~5.6.3"
},
"keywords": [],
24 changes: 3 additions & 21 deletions packages/bundle-source/src/bundle-source.js
Original file line number Diff line number Diff line change
@@ -27,29 +27,11 @@ const bundleSource = async (
const { bundleZipBase64 } = await import('./zip-base64.js');
return bundleZipBase64(startFilename, options, powers);
}
case 'getExport':
case 'nestedEvaluate':
case 'endoScript': {
const { bundleScript } = await import('./script.js');
return bundleScript(startFilename, options, powers);
}
case 'getExport': {
const { bundleNestedEvaluateAndGetExports } = await import(
'./nested-evaluate-and-get-exports.js'
);
return bundleNestedEvaluateAndGetExports(
startFilename,
moduleFormat,
powers,
);
}
case 'nestedEvaluate': {
const { bundleNestedEvaluateAndGetExports } = await import(
'./nested-evaluate-and-get-exports.js'
);
return bundleNestedEvaluateAndGetExports(
startFilename,
moduleFormat,
powers,
);
return bundleScript(startFilename, moduleFormat, options, powers);
}
default:
if (!SUPPORTED_FORMATS.includes(moduleFormat)) {
Loading