Skip to content

Commit d9c11e1

Browse files
committed
feat(types): ImportableBundle
1 parent d6e83fe commit d9c11e1

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

packages/import-bundle/src/index.js

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
// XXX Omit from typecheck for TypeScript packages depending upon
2-
// import-bundle.
3-
// TODO https://github.com/endojs/endo/issues/1254
4-
// @ts-nocheck
51
/* global globalThis */
62
/// <reference types="ses"/>
73

@@ -10,9 +6,27 @@ import { decodeBase64 } from '@endo/base64';
106
import { Fail } from '@endo/errors';
117
import { wrapInescapableCompartment } from './compartment-wrapper.js';
128

13-
// importBundle takes the output of bundle-source, and returns a namespace
14-
// object (with .default, and maybe other properties for named exports)
9+
/**
10+
* The bundle importer is designed for (serializable) source modules but can
11+
* accomodate native module exports (unserializable) too in a 'test' format.
12+
* @typedef {import('@endo/bundle-source').ModuleFormat | 'test'} ImportableBundleFormat
13+
*/
1514

15+
/**
16+
* The bundle importer is designed for (serializable) source modules but can
17+
* accomodate native module exports (unserializable) too in a 'test' format.
18+
* @typedef {import('@endo/bundle-source').BundleSourceResult<any> | {moduleFormat: 'test'}} ImportableBundle
19+
*/
20+
21+
/**
22+
* importBundle takes the output of `bundleSource` or `bundleTestExports`, and returns a namespace
23+
* object (with .default, and maybe other properties for named exports)
24+
*
25+
* @param {ImportableBundle} bundle
26+
* @param {object} [options]
27+
* @param {object} [powers]
28+
* @returns {Promise<Record<string, any>>}
29+
*/
1630
export async function importBundle(bundle, options = {}, powers = {}) {
1731
await null;
1832
const {
@@ -56,8 +70,10 @@ export async function importBundle(bundle, options = {}, powers = {}) {
5670

5771
let compartment;
5872

73+
assert('moduleFormat' in bundle);
5974
const { moduleFormat } = bundle;
6075
if (moduleFormat === 'endoZipBase64') {
76+
assert('endoZipBase64' in bundle);
6177
const { endoZipBase64 } = bundle;
6278
const bytes = decodeBase64(endoZipBase64);
6379
const archive = await parseArchive(bytes, bundleUrl, {
@@ -71,7 +87,6 @@ export async function importBundle(bundle, options = {}, powers = {}) {
7187
const { namespace } = await archive['import']({
7288
globals: endowments,
7389
__shimTransforms__: transforms,
74-
// @ts-expect-error TS2740 missing properties from type
7590
Compartment: CompartmentToUse,
7691
});
7792
// namespace.default has the default export
@@ -131,8 +146,9 @@ export async function importBundle(bundle, options = {}, powers = {}) {
131146
);
132147
}
133148

149+
assert('source' in bundle);
134150
let { source } = bundle;
135-
const { sourceMap } = bundle;
151+
const sourceMap = 'sourceMap' in bundle ? bundle.sourceMap : '';
136152
if (moduleFormat === 'getExport') {
137153
// The 'getExport' format is a string which defines a wrapper function
138154
// named `getExport()`. This function provides a `module` to the
@@ -142,7 +158,7 @@ export async function importBundle(bundle, options = {}, powers = {}) {
142158
// (making it an expression). We also want to append the `sourceMap`
143159
// comment so `evaluate` can attach useful debug information. Finally, to
144160
// extract the namespace object, we need to invoke this function.
145-
source = `(${source})\n${sourceMap || ''}`;
161+
source = `(${source})\n${sourceMap}`;
146162
} else if (moduleFormat === 'nestedEvaluate') {
147163
// The 'nestedEvaluate' format is similar, except the wrapper function
148164
// (now named `getExportWithNestedEvaluate`) wraps more than a single
@@ -155,7 +171,7 @@ export async function importBundle(bundle, options = {}, powers = {}) {
155171
// module. The sourceMap name for other modules will be derived from
156172
// `filePrefix` and the relative import path of each module.
157173
endowments.nestedEvaluate = src => compartment.evaluate(src);
158-
source = `(${source})\n${sourceMap || ''}`;
174+
source = `(${source})\n${sourceMap}`;
159175
} else if (moduleFormat === 'endoScript') {
160176
// The 'endoScript' format is just a script.
161177
} else {

packages/import-bundle/test/import-bundle.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,14 @@ test('inescapable global properties, zip base64 format', async t => {
192192
});
193193

194194
test('test the test format', async t => {
195-
const bundle = {
195+
const bundle = /** @type {const} */ ({
196196
moduleFormat: 'test',
197197
[Symbol.for('exports')]: {
198198
z: 43,
199199
default: 42,
200200
a: 41,
201201
},
202-
};
202+
});
203203
const ns = await importBundle(bundle);
204204
t.is(ns.default, 42);
205205
t.deepEqual(Object.keys(ns), ['a', 'default', 'z']);

0 commit comments

Comments
 (0)