Skip to content

Commit ddd064a

Browse files
author
Guy Bedford
authored
fix: specifier mappings in ComponentizeJS (#167)
1 parent 303024d commit ddd064a

File tree

4 files changed

+60
-11
lines changed

4 files changed

+60
-11
lines changed

src/componentize.js

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const isWindows = platform === 'win32';
2525
const DEBUG_BINDINGS = false;
2626
const DEBUG_CALLS = false;
2727
const DEBUG_BUILD = false;
28+
const DEBUG_BINARY = false;
2829

2930
function maybeWindowsPath(path) {
3031
if (!path) return path;
@@ -45,11 +46,23 @@ export async function componentize(jsSource, witWorld, opts) {
4546
worldName,
4647
disableFeatures = [],
4748
enableFeatures = [],
48-
aotCache = fileURLToPath(new URL(`../lib/starlingmonkey_ics.wevalcache`, import.meta.url))
49+
aotCache = fileURLToPath(
50+
new URL(`../lib/starlingmonkey_ics.wevalcache`, import.meta.url)
51+
),
4952
} = opts;
5053

51-
const engine = opts.engine || fileURLToPath(
52-
new URL(opts.enableAot ? `../lib/starlingmonkey_embedding_weval.wasm` : `../lib/starlingmonkey_embedding${DEBUG_BUILD ? '.debug' : ''}.wasm`, import.meta.url));
54+
const engine =
55+
opts.engine ||
56+
fileURLToPath(
57+
new URL(
58+
opts.enableAot
59+
? `../lib/starlingmonkey_embedding_weval.wasm`
60+
: `../lib/starlingmonkey_embedding${
61+
DEBUG_BUILD ? '.debug' : ''
62+
}.wasm`,
63+
import.meta.url
64+
)
65+
);
5366

5467
await lexerInit;
5568
let jsImports = [];
@@ -61,13 +74,13 @@ export async function componentize(jsSource, witWorld, opts) {
6174
}
6275

6376
let guestImports = [];
64-
jsImports.map((k) => {
65-
guestImports.push(k.n);
77+
jsImports.map(({ t, n }) => {
78+
if (typeof n === 'string' && (t === 1 || t === 2)) guestImports.push(n);
6679
});
6780

6881
let guestExports = [];
6982
jsExports.map((k) => {
70-
guestExports.push(k.n);
83+
if (k.n) guestExports.push(k.n);
7184
});
7285

7386
// we never disable a feature that is already in the target world usage
@@ -131,7 +144,23 @@ export async function componentize(jsSource, witWorld, opts) {
131144
// rewrite the JS source import specifiers to reference import wrappers
132145
let source = '',
133146
curIdx = 0;
147+
const importSpecifiers = new Set([...importWrappers.map(([impt]) => impt)]);
134148
for (const jsImpt of jsImports) {
149+
if (jsImpt.t !== 1 && jsImpt.t !== 2) continue;
150+
if (!jsImpt.n) continue;
151+
if (!importSpecifiers.has(jsImpt.n)) {
152+
throw new Error(
153+
`Import '${
154+
jsImpt.n
155+
}' is not defined by the WIT world. Available imports are: ${[
156+
...importSpecifiers,
157+
]
158+
.map((impt) => `'${impt}'`)
159+
.join(
160+
', '
161+
)}.\nMake sure to use a bundler for JS dependencies such as esbuild or RollupJS.`
162+
);
163+
}
135164
const specifier = jsSource.slice(jsImpt.s, jsImpt.e);
136165
source += jsSource.slice(curIdx, jsImpt.s);
137166
source += `./${specifier.replace(':', '__').replace('/', '$')}.js`;
@@ -163,10 +192,8 @@ export async function componentize(jsSource, witWorld, opts) {
163192
let hostenv = {};
164193

165194
if (opts.env) {
166-
hostenv = (typeof opts.env === 'object')
167-
? opts.env
168-
: process.env;
169-
};
195+
hostenv = typeof opts.env === 'object' ? opts.env : process.env;
196+
}
170197

171198
const env = {
172199
...hostenv,
@@ -215,7 +242,7 @@ export async function componentize(jsSource, witWorld, opts) {
215242
'--init-func',
216243
'componentize.wizer',
217244
`-i ${input}`,
218-
`-o ${output}`
245+
`-o ${output}`,
219246
],
220247
{
221248
stdio: [null, stdout, stderr],
@@ -384,6 +411,10 @@ export async function componentize(jsSource, witWorld, opts) {
384411
worldName
385412
);
386413

414+
if (DEBUG_BINARY) {
415+
await writeFile('binary.wasm', finalBin);
416+
}
417+
387418
const component = await metadataAdd(
388419
await componentNew(
389420
finalBin,

test/cases/bad-binding/source.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import blah from 'not:world-defined';

test/cases/bad-binding/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { strictEqual } from 'node:assert';
2+
3+
export function err (error) {
4+
strictEqual(error.message, "Import 'not:world-defined' is not defined by the WIT world. Available imports are: 'local:char/chars'.\nMake sure to use a bundler for JS dependencies such as esbuild or RollupJS.");
5+
}

test/cases/bad-binding/world.wit

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package local:%char;
2+
3+
interface chars {
4+
/// A function that returns a character
5+
return-char: func() -> char;
6+
/// A function that accepts a character
7+
take-char: func(x: char);
8+
}
9+
10+
world the-world {
11+
import chars;
12+
}

0 commit comments

Comments
 (0)