Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

await for evaluation of async module #494

Open
DPOH-VAR opened this issue Sep 15, 2024 · 1 comment
Open

await for evaluation of async module #494

DPOH-VAR opened this issue Sep 15, 2024 · 1 comment

Comments

@DPOH-VAR
Copy link

DPOH-VAR commented Sep 15, 2024

JavaScript includes a setTimeout function: yes
Functions are a type of primitive value in JavaScript: yes
Objects can be shared between isolates: no

Is there a way to wait for an async module to execute?

import ivm from "isolated-vm";
const isolate = new ivm.Isolate();
const context = await isolate.createContext();
const module = await isolate.compileModule(/* language=javascript */ `
    export const x = 10;
    await new Promise(resolve => globalThis.hook = resolve);
    export const y = 20;
`);
await module.instantiate(context, () => null);
const moduleEvalPromise = module.evaluate({promise: true, reference: true, timeout: 10});
const hook = await context.global.get("hook");

setTimeout(hook, 100);

moduleEvalPromise.then(async (moduleValue) => {
    console.log("Module evaluated", moduleValue);
    console.log("Value-X", await module.namespace.get("x"));
    console.log("Value-Y", await module.namespace.get("y")); // error
});

I get an error when accessing variable y

Module evaluated undefined
Value-X 10
node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
    ^

ReferenceError: y is not defined
    at (<isolated-vm boundary>)
    at main.mjs:18:51

But this code wotks fine:

moduleEvalPromise.then(async (moduleValue) => {
    console.log("Module evaluated", moduleValue); // undefined
    setTimeout(async () => {
        console.log("Value-X", await module.namespace.get("x"));
        console.log("Value-Y", await module.namespace.get("y"));
    }, 200); // wait longer
});

I think async module.evaluate resolves before the module is executed.

Is it possible to get Promise or callback when the module will be executed to the end?

@laverdet
Copy link
Owner

v8 and JavaScript added top-level await after the implementation in isolated-vm, so this is probably just a limitation of the current implementation. I've been working on a rewrite but obviously that won't help you now, since that won't be ready for quite some time. You can probably work around it today by injecting a promise resolution at the end of the module and waiting on that instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants