Skip to content

Commit 0dbb69a

Browse files
committed
fix(compartment-mapper): handle async parsers
This updates the code and types to handle async parsers. Currently, there are no async parsers in `@endo/compartment-mapper`, which is a reasonable excuse for why they were not working. While this looks like a much was changed, it is mostly type-related. Some extra guards were added and code split out within `map-parser.js` to support both the async and sync parser use-cases, while maximizing logic reuse.
1 parent 0fb7919 commit 0dbb69a

5 files changed

Lines changed: 262 additions & 244 deletions

File tree

packages/compartment-mapper/src/import-hook.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@
99
*
1010
* @module
1111
*/
12-
12+
import { asyncTrampoline, syncTrampoline } from '@endo/trampoline';
13+
import { resolve } from './node-module-specifier.js';
14+
import {
15+
attenuateModuleHook,
16+
enforcePolicyByModule,
17+
enforcePackagePolicyByCanonicalName,
18+
} from './policy.js';
19+
import { ATTENUATORS_COMPARTMENT } from './policy-format.js';
20+
import { unpackReadPowers } from './powers.js';
1321
/**
1422
* @import {
1523
* ImportHook,
@@ -43,18 +51,19 @@
4351
* CanonicalName,
4452
* LocalModuleSource,
4553
* ModuleSourceHook,
54+
* ParseFn,
55+
* AsyncParseFn,
4656
* } from './types.js'
4757
*/
4858

49-
import { asyncTrampoline, syncTrampoline } from '@endo/trampoline';
50-
import { resolve } from './node-module-specifier.js';
51-
import {
52-
attenuateModuleHook,
53-
enforcePolicyByModule,
54-
enforcePackagePolicyByCanonicalName,
55-
} from './policy.js';
56-
import { ATTENUATORS_COMPARTMENT } from './policy-format.js';
57-
import { unpackReadPowers } from './powers.js';
59+
/**
60+
* Type guard that narrows a `ParseFn | AsyncParseFn` to `ParseFn` by checking
61+
* for the `isSyncParser` flag.
62+
*
63+
* @param {ParseFn | AsyncParseFn} parse
64+
* @returns {parse is ParseFn}
65+
*/
66+
const isSyncParseFn = parse => 'isSyncParser' in parse && !!parse.isSyncParser;
5867

5968
// q, as in quote, for quoting strings in error messages.
6069
const { quote: q } = assert;
@@ -324,8 +333,7 @@ const executeLocalModuleSourceHook = (
324333
* {@link StaticModuleType} for a particular {@link CompartmentDescriptor} (or
325334
* `undefined`).
326335
*
327-
* Supports both {@link SyncChooseModuleDescriptorOperators sync} and
328-
* {@link AsyncChooseModuleDescriptorOperators async} operators.
336+
* Supports both sync and async operators.
329337
*
330338
* Used by both {@link makeImportNowHookMaker} and {@link makeImportHookMaker}.
331339
*
@@ -839,13 +847,14 @@ export function makeImportNowHookMaker(
839847
}
840848
};
841849

842-
if (!('isSyncParser' in parse)) {
850+
if (!isSyncParseFn(parse)) {
843851
return function impossibleTransformImportNowHook() {
844852
throw new Error(
845853
'Dynamic requires are only possible with synchronous parsers and no asynchronous module transforms in options',
846854
);
847855
};
848856
}
857+
const /** @type {ParseFn} */ syncParse = parse;
849858

850859
const compartmentDescriptor =
851860
compartmentDescriptors[packageLocation] || create(null);
@@ -924,7 +933,7 @@ export function makeImportNowHookMaker(
924933
},
925934
{
926935
maybeRead: maybeReadNow,
927-
parse,
936+
parse: syncParse,
928937
shouldDeferError,
929938
},
930939
);

packages/compartment-mapper/src/link.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ export const link = (
332332
/** @type {ShouldDeferError} */
333333
const shouldDeferError = language => {
334334
if (language && has(parserForLanguage, language)) {
335-
return /** @type {ParserImplementation} */ (parserForLanguage[language])
336-
.heuristicImports;
335+
return parserForLanguage[language].heuristicImports;
337336
} else {
338337
// If language is undefined or there's no parser, the error we could consider deferring is surely related to
339338
// that. Nothing to throw here.

0 commit comments

Comments
 (0)