How to properly use isolated-vm to execute sandboxed code in Node.js?

I am migrating from vm2 to isolated-vm for executing sandboxed code in Node.js. However, my current implementation always returns undefined for the result. Here is my code:

import ivm from 'isolated-vm';

export async function executeSandboxedCode(expression: string, params: any): Promise<any> {
  const context = {
    // populate context with necessary parameters
    ...params,
  };

  try {
    const isolate = new ivm.Isolate();
    const isolateContext = await isolate.createContext();
    
    const jail = isolateContext.global;
    await jail.set('global', jail.derefInto());

    const script = await isolate.compileScript(`
      (function(context) {
        ${expression}
      })(global.context);
    `);

    await jail.set('context', new ivm.ExternalCopy(context).copyInto());
    const result = await script.run(isolateContext);

    return result;
  } catch (error) {
    throw new Error(`Failure in process: ${error.message}`);
  }
}

What I tried:

  1. Assigned params to the global.context object.

  2. Compiled the script with the expression in a function.

  3. Used return in the expression to ensure a value is returned.

  4. Added error handling for context.

Expected:

The result from script.run(isolateContext) should contain the evaluated result based on the context parameters.

Actual:

The result always comes back as undefined.

What am I doing wrong?