Skip to content
Draft
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
9 changes: 9 additions & 0 deletions .changeset/ripe-showers-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@endo/module-source': minor
---

Fixes the type of `SourceMapHook` and introduces proper `.ts` type sources checked by `tsc`. Types that were previously inlined as JSDoc typedefs (`SourceMapHook`, `SourceMapHookDetails`, `SourceMapObject`, `ModuleSourceOptions`, `TransformSourceParams`) are now defined in `src/types/module-source.ts` and re-exported from the package root via a new `src/external.types.d.ts` entry.

Adds a `./analyzer.js` subpath export with `analyzeModule(options?)`. The returned context object exposes `analyzePass` and `transformPass` (plain `{ visitor }` objects) and a `buildRecord()` function. This is the primitive that `@endo/parser-pipeline` uses to drive module analysis; it is also used internally by the `ModuleSource` constructor, so the exported API is not specific to the pipeline.

Removes the `PluginFactory` abstraction and `visitorFromPlugin` helper: Babel plugins now return plain `{ visitor }` objects directly, with `@babel/types` imported at module scope.
4 changes: 4 additions & 0 deletions packages/module-source/analyzer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line import/export
export * from './src/external.types.js';

export { analyzeModule } from './src/analyzer.js';
3 changes: 3 additions & 0 deletions packages/module-source/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
// eslint-disable-next-line import/export
export * from './src/external.types.js';

export { ModuleSource } from './src/module-source.js';
29 changes: 28 additions & 1 deletion packages/module-source/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,17 @@
"exports": {
".": {
"xs": "./src-xs/index.js",
"types": "./index.d.ts",
"default": "./index.js"
},
"./shim.js": "./shim.js",
"./shim.js": {
"types": "./src/shim.types.d.ts",
"default": "./shim.js"
},
"./analyzer.js": {
"types": "./analyzer.d.ts",
"default": "./analyzer.js"
},
"./package.json": "./package.json"
},
"scripts": {
Expand All @@ -51,6 +59,8 @@
},
"devDependencies": {
"@endo/ses-ava": "workspace:^",
"@types/babel__generator": "~7.27.0",
"@types/babel__traverse": "~7.28.0",
"ava": "catalog:dev",
"babel-eslint": "^10.1.0",
"benchmark": "^2.1.4",
Expand Down Expand Up @@ -84,8 +94,25 @@
"^@endo/module-source(?:/.*)?$"
]
}
],
"jsdoc/check-tag-names": [
"error",
{
"definedTags": [
"privateRemarks"
]
}
]
},
"overrides": [
{
"files": "**/*.ts",
"rules": {
"vars-on-top": "off",
"no-var": "off"
}
}
],
"ignorePatterns": [
"test/fixtures/"
]
Expand Down
48 changes: 48 additions & 0 deletions packages/module-source/src/analyzer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Low-level module analysis primitives for ESM.
*
* {@link analyzeModule} returns a per-parse context object
* holding plain `{ visitor }` objects and a `buildRecord` function.
*
* Consumers are responsible for:
* 1. Traversing the AST with `ctx.analyzePass.visitor`.
* 2. Traversing the (mutated) AST with `ctx.transformPass.visitor`.
* 3. Generating code.
* 4. Calling `ctx.buildRecord(code, location)` to produce the module record.
*
* @module
*/

/**
* @import {ModuleAnalysisContext, AnalysisOptions} from './types/analyzer.js'
*/

import makeModulePlugins from './babel-plugin.js';
import { createSourceOptions } from './source-options.js';
import { buildFunctorSource, buildModuleRecord } from './functor.js';

/**
* Creates a fresh ESM analysis context for a single module parse.
*
* @param {AnalysisOptions} [options]
* @returns {ModuleAnalysisContext}
*/
export const analyzeModule = (options = {}) => {
const { allowHidden = false } = options;
const sourceOptions = createSourceOptions({ allowHidden });
const { analyzePlugin, transformPlugin } = makeModulePlugins(sourceOptions);

return {
analyzePass: analyzePlugin,
transformPass: transformPlugin,

buildRecord(generatedCode, location) {
const functorSource = buildFunctorSource(
generatedCode,
sourceOptions,
location,
);
return buildModuleRecord(sourceOptions, functorSource);
},
};
};
Loading
Loading