Skip to content

Commit

Permalink
fix: specifier mappings in ComponentizeJS (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford authored Dec 11, 2024
1 parent 303024d commit ddd064a
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 11 deletions.
53 changes: 42 additions & 11 deletions src/componentize.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const isWindows = platform === 'win32';
const DEBUG_BINDINGS = false;
const DEBUG_CALLS = false;
const DEBUG_BUILD = false;
const DEBUG_BINARY = false;

function maybeWindowsPath(path) {
if (!path) return path;
Expand All @@ -45,11 +46,23 @@ export async function componentize(jsSource, witWorld, opts) {
worldName,
disableFeatures = [],
enableFeatures = [],
aotCache = fileURLToPath(new URL(`../lib/starlingmonkey_ics.wevalcache`, import.meta.url))
aotCache = fileURLToPath(
new URL(`../lib/starlingmonkey_ics.wevalcache`, import.meta.url)
),
} = opts;

const engine = opts.engine || fileURLToPath(
new URL(opts.enableAot ? `../lib/starlingmonkey_embedding_weval.wasm` : `../lib/starlingmonkey_embedding${DEBUG_BUILD ? '.debug' : ''}.wasm`, import.meta.url));
const engine =
opts.engine ||
fileURLToPath(
new URL(
opts.enableAot
? `../lib/starlingmonkey_embedding_weval.wasm`
: `../lib/starlingmonkey_embedding${
DEBUG_BUILD ? '.debug' : ''
}.wasm`,
import.meta.url
)
);

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

let guestImports = [];
jsImports.map((k) => {
guestImports.push(k.n);
jsImports.map(({ t, n }) => {
if (typeof n === 'string' && (t === 1 || t === 2)) guestImports.push(n);
});

let guestExports = [];
jsExports.map((k) => {
guestExports.push(k.n);
if (k.n) guestExports.push(k.n);
});

// we never disable a feature that is already in the target world usage
Expand Down Expand Up @@ -131,7 +144,23 @@ export async function componentize(jsSource, witWorld, opts) {
// rewrite the JS source import specifiers to reference import wrappers
let source = '',
curIdx = 0;
const importSpecifiers = new Set([...importWrappers.map(([impt]) => impt)]);
for (const jsImpt of jsImports) {
if (jsImpt.t !== 1 && jsImpt.t !== 2) continue;
if (!jsImpt.n) continue;
if (!importSpecifiers.has(jsImpt.n)) {
throw new Error(
`Import '${
jsImpt.n
}' is not defined by the WIT world. Available imports are: ${[
...importSpecifiers,
]
.map((impt) => `'${impt}'`)
.join(
', '
)}.\nMake sure to use a bundler for JS dependencies such as esbuild or RollupJS.`
);
}
const specifier = jsSource.slice(jsImpt.s, jsImpt.e);
source += jsSource.slice(curIdx, jsImpt.s);
source += `./${specifier.replace(':', '__').replace('/', '$')}.js`;
Expand Down Expand Up @@ -163,10 +192,8 @@ export async function componentize(jsSource, witWorld, opts) {
let hostenv = {};

if (opts.env) {
hostenv = (typeof opts.env === 'object')
? opts.env
: process.env;
};
hostenv = typeof opts.env === 'object' ? opts.env : process.env;
}

const env = {
...hostenv,
Expand Down Expand Up @@ -215,7 +242,7 @@ export async function componentize(jsSource, witWorld, opts) {
'--init-func',
'componentize.wizer',
`-i ${input}`,
`-o ${output}`
`-o ${output}`,
],
{
stdio: [null, stdout, stderr],
Expand Down Expand Up @@ -384,6 +411,10 @@ export async function componentize(jsSource, witWorld, opts) {
worldName
);

if (DEBUG_BINARY) {
await writeFile('binary.wasm', finalBin);
}

const component = await metadataAdd(
await componentNew(
finalBin,
Expand Down
1 change: 1 addition & 0 deletions test/cases/bad-binding/source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import blah from 'not:world-defined';
5 changes: 5 additions & 0 deletions test/cases/bad-binding/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { strictEqual } from 'node:assert';

export function err (error) {
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.");
}
12 changes: 12 additions & 0 deletions test/cases/bad-binding/world.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package local:%char;

interface chars {
/// A function that returns a character
return-char: func() -> char;
/// A function that accepts a character
take-char: func(x: char);
}

world the-world {
import chars;
}

0 comments on commit ddd064a

Please sign in to comment.