Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@imolorhe
Copy link
Collaborator

@imolorhe imolorhe commented Oct 11, 2025

Currently only the initialisation message is sent to the iframe and subsequent calls don't satisfy the load event so never gets sent.

Fixes

#2908

Checks

  • Ran yarn test-build
  • Updated relevant documentations
  • Updated matching config options in altair-static

Changes proposed in this pull request:

Summary by Sourcery

Ensure that messages sent to the sandbox iframe after initialization are delivered by caching its load state and awaiting it in the send method

Bug Fixes:

  • Fix issue where only the initial postMessage was delivered to the iframe by caching the load event

Enhancements:

  • Introduce an iframeLoadedPromise to replace per-call load event listeners and convert send() to an async method that awaits the iframe load

Summary by CodeRabbit

  • Bug Fixes
    • Fixed intermittent issues where pre-request scripts could be skipped or fail if the embedded panel wasn’t fully loaded. Communication now waits until the panel is ready, ensuring consistent execution and fewer errors.
  • Refactor
    • Streamlined readiness handling for the embedded frame to use a single, reusable check, reducing event listener overhead and race conditions for improved stability.

@gemini-code-assist
Copy link

Summary of Changes

Hello @imolorhe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where messages sent to an iframe were not reliably delivered after its initial load. By implementing a mechanism to cache the iframe's loaded state using a promise, the system now ensures that all subsequent message sending operations correctly wait for the iframe to be fully ready, thereby guaranteeing reliable communication and improving the robustness of the application.

Highlights

  • Iframe Load State Caching: Introduced a Promise named iframeLoadedPromise that resolves once the embedded iframe has fully loaded, effectively caching its ready state.
  • Asynchronous Message Sending: Modified the send method to be asynchronous, ensuring that it awaits the iframeLoadedPromise before attempting to post messages to the iframe's content window. This guarantees messages are sent only after the iframe is ready.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 11, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR introduces a cached iframe-loaded promise to track when the iframe is ready and refactors the send method to await this promise before posting messages, ensuring that all messages are sent only after the iframe has fully loaded.

Sequence diagram for sending messages to iframe after load

sequenceDiagram
participant Client as EvaluatorFrameClient
participant Iframe
Client->>Iframe: Add 'load' event listener (on creation)
Client->>Client: Create iframeLoadedPromise
Client->>Iframe: send(type, payload)
Client->>Client: await iframeLoadedPromise
Iframe-->>Client: 'load' event resolves promise
Client->>Iframe: postMessage({ type, payload }, sandboxUrl)
Loading

Class diagram for updated EvaluatorFrameClient

classDiagram
class ScriptEvaluatorClient {
}
class EvaluatorFrameClient {
  - iframeLoadedPromise: Promise<void>
  + constructor(sandboxUrl: string)
  + send(type: string, payload: any): Promise<void>
  + onError(handler: (err: any) => void): void
}
ScriptEvaluatorClient <|-- EvaluatorFrameClient
Loading

File-Level Changes

Change Details Files
Cache iframe load state with a promise
  • Added private iframeLoadedPromise property returning a Promise
  • Set up an event listener on the iframe 'load' event to resolve the promise
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
Refactor send method to await iframe readiness
  • Changed send signature to async and return Promise
  • Removed inline load event listener inside send
  • Await iframeLoadedPromise before calling postMessage on contentWindow
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#2908 Fix hanging and timeout issues when calling altair.storage and altair.helpers.request methods in pre-request scripts on Chromium-based platforms.
#2908 Ensure that altair.storage and altair.helpers.request methods work normally in pre-request scripts on macOS app and Chrome extension, as they do on Firefox.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Oct 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Refactors the pre-request EvaluatorFrameClient to await a single iframeLoadedPromise that resolves on the iframe load event before sending messages. The send method is now async, returns Promise, and posts messages only after the iframe has loaded.

Changes

Cohort / File(s) Summary
Pre-request iframe client initialization and messaging
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
Added private iframeLoadedPromise resolved on iframe load; changed send to async Promise; send now awaits iframeLoadedPromise instead of attaching a per-call load listener before postMessage.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant PR as Pre-request Script
  participant EFC as EvaluatorFrameClient
  participant IF as Iframe (Evaluator)

  Note over EFC,IF: Initialization
  EFC->>IF: Create iframe and attach 'load' listener
  IF-->>EFC: 'load' event resolves iframeLoadedPromise

  Note over PR,EFC: Sending a message
  PR->>EFC: send(message)
  activate EFC
  EFC->>EFC: await iframeLoadedPromise
  EFC->>IF: postMessage(message)
  deactivate EFC

  Note over PR,IF: Response handling (unchanged)
  IF-->>PR: message response via postMessage
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A hop, a wait, a gentle load,
I pause before I send my code.
No more hangs in Chromium’s den—
I ping the frame, but only when
The window’s ready, ears alert—
Messages land, and none get hurt. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly describes the primary change of caching the iframe loaded state to enable subsequent message sending and directly corresponds to the modifications in the pull request. It clearly identifies the new functionality and is concise and specific. No additional detail is needed for clarity.
Linked Issues Check ✅ Passed The introduced cached promise and updated send method ensure that each postMessage waits for the iframe to load, directly resolving the hang of altair.storage and altair.helpers calls in pre-request scripts as described in issue #2908. This change restores normal operation of storage and helper functions in Chromium-based environments without introducing regressions. Therefore, the code fully addresses the primary objectives of the linked issue.
Out of Scope Changes Check ✅ Passed All modifications are confined to evaluator-client.factory.ts and relate solely to caching the iframe load event and adjusting message sending logic, which directly aligns with the bug fix described in issue #2908. There are no unrelated changes to other services, documentation, or configuration. Thus, no out-of-scope changes are present.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch imolorhe/fix-evaluator-frame-client

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix an issue where messages could not be sent to the iframe after the initial load. The approach of using a promise (iframeLoadedPromise) to cache the loaded state is correct. However, the current implementation has two main issues. First, there is a critical race condition in the initialization of iframeLoadedPromise that could cause it to never resolve. Second, changing the send method to be asynchronous breaks the contract with the base ScriptEvaluatorClient class. My review includes detailed comments on how to address both of these issues.

Comment on lines +19 to +23
private iframeLoadedPromise = new Promise<void>((resolve) => {
this.iframe.addEventListener('load', () => {
resolve();
});
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There is a potential race condition here. The iframe is created and its src is set within createIframe(), which is called during the initialization of the iframe property. The browser might start loading and fire the load event before this iframeLoadedPromise is initialized and the load event listener is attached. If that happens, the promise will never resolve, causing send to hang indefinitely.

To fix this, you should ensure the load event listener is attached before the iframe.src is set. This typically requires refactoring the initialization logic. For example, you could move the iframe creation and setup into the constructor to control the order of operations:

export class EvaluatorFrameClient extends ScriptEvaluatorClient {
  private iframe: HTMLIFrameElement;
  private readonly iframeLoadedPromise: Promise<void>;
  // ...

  constructor(private sandboxUrl: string) {
    super();
    this.iframe = document.createElement('iframe');

    this.iframeLoadedPromise = new Promise<void>(resolve => {
      this.iframe.addEventListener('load', () => resolve());
    });

    this.iframe.style.display = 'none';
    const sandboxUrl = new URL(this.sandboxUrl);
    sandboxUrl.searchParams.set('sc', window.location.origin);
    sandboxUrl.searchParams.set('action', 'evaluator');
    this.iframe.src = sandboxUrl.toString();

    this.iframe.sandbox.add('allow-scripts');
    this.iframe.sandbox.add('allow-same-origin');
    this.iframe.referrerPolicy = 'no-referrer';
    document.body.appendChild(this.iframe);

    // You would need to remove the `createIframe` method and the `iframe` property initializer.
  }

  // ...
}

This ensures the listener is always attached before loading begins.

Comment on lines +64 to 67
async send(type: string, payload: any): Promise<void> {
await this.iframeLoadedPromise;
this.iframe.contentWindow?.postMessage({ type, payload }, this.sandboxUrl);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Changing the return type of send from void to Promise<void> is a good fix for this class, but it makes it inconsistent with the base ScriptEvaluatorClient abstract class, which defines send as returning void. This violates the Liskov substitution principle and can lead to unexpected behavior, especially since the other implementation EvaluatorWorkerClient still returns void.

To fix this properly, you should:

  1. Update the send method signature in the abstract class ScriptEvaluatorClient (in packages/altair-core/src/script/types.ts) to abstract send(type: string, payload: any): Promise<void>;.
  2. Update the send method in EvaluatorWorkerClient to also be async and return a Promise<void>.
// in EvaluatorWorkerClient
async send(type: string, payload: any): Promise<void> {
  this.worker.postMessage({
    type,
    payload,
  });
}

This will ensure all implementations are consistent and callers can reliably await the send operation.

@github-actions
Copy link

Visit the preview URL for this PR (updated for commit bdfe573):

https://altair-gql--pr2909-imolorhe-fix-evaluat-ppo341sn.web.app

(expires Sat, 18 Oct 2025 01:47:29 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 02d6323d75a99e532a38922862e269d63351a6cf

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts (1)

75-75: Remove dead code: removeAllListeners doesn't exist on HTMLIFrameElement.

The removeAllListeners method is not part of the HTMLIFrameElement API. This line has no effect.

     this.messageListeners.forEach((listener) => {
       window.removeEventListener('message', listener);
     });
-    this.iframe.removeAllListeners?.();
     this.iframe.remove();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b92e384 and bdfe573.

📒 Files selected for processing (1)
  • packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.github/instructions/app-testing.instructions.md)

Follow project code style using ESLint and Prettier

**/*.ts: Use explicit type annotations for function parameters and return types
Prefer interfaces over type aliases for object shapes
Use union types and literal types for better type safety
Leverage generic types for reusable components
Group imports: external libraries first, then internal modules
Use absolute imports from package roots when possible
Prefer named exports over default exports
Use custom error classes that extend Error
Implement proper error boundaries and handling
Log errors with sufficient context for debugging
Use observables (RxJS) for reactive programming patterns where appropriate
Manage subscriptions to avoid memory leaks
Use appropriate RxJS operators for data transformation
Handle errors in observable streams
Use async/await for sequential operations
Handle promise rejections properly
Use Promise.all() for concurrent operations
Implement timeout handling for long-running operations
Dispose of resources properly (subscriptions, event listeners)
Use weak references where appropriate
Avoid creating unnecessary objects in hot paths
Profile memory usage for performance-critical code
Use tree-shaking-friendly imports
Lazy load heavy modules when possible
Monitor bundle size impacts of new dependencies
Use dynamic imports for code splitting
Validate and sanitize all user inputs
Implement proper XSS and injection prevention
Validate API responses before processing
Sanitize sensitive data in logs
Follow secure coding practices
Group related functionality in modules
Keep files focused and not too large
Use consistent naming conventions
Organize imports and exports clearly
Write JSDoc comments for public APIs
Keep documentation up to date with code changes (inline docs)
Use meaningful variable and function names
Handle environment-specific APIs properly
Use TypeScript features appropriate for the configured version

Files:

  • packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/main.instructions.md)

Use TypeScript for implementation across the codebase

Files:

  • packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
packages/altair-app/**/*.{ts,html}

📄 CodeRabbit inference engine (.github/instructions/main.instructions.md)

Implement and modify the main web app using Angular conventions within packages/altair-app

Files:

  • packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: sites / Deploy Login Redirect / Deploy Login Redirect
  • GitHub Check: sites / Deploy Sandbox / Deploy Iframe Sandbox
  • GitHub Check: sites / Deploy Web App / Deploy Web App
  • GitHub Check: sites / Deploy Docs / Deploy Documentation
  • GitHub Check: Sourcery review
  • GitHub Check: electron / electron (windows-latest)
  • GitHub Check: electron / electron (ubuntu-latest)
  • GitHub Check: tests / test (macos-latest)
  • GitHub Check: electron / electron (macos-latest)
  • GitHub Check: docker / docker
  • GitHub Check: tests / test (ubuntu-latest)
  • GitHub Check: tests / api-e2e-test
  • GitHub Check: tests / e2e-test (macos-latest)
  • GitHub Check: tests / e2e-test (ubuntu-latest)
  • GitHub Check: tauri / tauri (windows-latest)
  • GitHub Check: tauri / tauri (macos-latest, --target x86_64-apple-darwin)
  • GitHub Check: tauri / tauri (ubuntu-22.04)
  • GitHub Check: tauri / tauri (macos-latest, --target aarch64-apple-darwin)
  • GitHub Check: build_and_preview

Comment on lines +19 to +23
private iframeLoadedPromise = new Promise<void>((resolve) => {
this.iframe.addEventListener('load', () => {
resolve();
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add error handling to prevent indefinite hangs if iframe fails to load.

The cached promise approach correctly fixes the reported bug. However, if the iframe fails to load, iframeLoadedPromise never resolves, causing all send() calls to hang indefinitely.

Consider this diff to add error and timeout handling:

-  private iframeLoadedPromise = new Promise<void>((resolve) => {
-    this.iframe.addEventListener('load', () => {
-      resolve();
-    });
-  });
+  private iframeLoadedPromise = new Promise<void>((resolve, reject) => {
+    const timeoutId = setTimeout(() => {
+      reject(new Error('Iframe failed to load within timeout'));
+    }, 30000); // 30 second timeout
+
+    this.iframe.addEventListener('load', () => {
+      clearTimeout(timeoutId);
+      resolve();
+    });
+
+    this.iframe.addEventListener('error', (e) => {
+      clearTimeout(timeoutId);
+      reject(new Error('Iframe failed to load: ' + e.message));
+    });
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private iframeLoadedPromise = new Promise<void>((resolve) => {
this.iframe.addEventListener('load', () => {
resolve();
});
});
private iframeLoadedPromise = new Promise<void>((resolve, reject) => {
// Reject if iframe doesn’t load within 30 seconds
const timeoutId = setTimeout(() => {
reject(new Error('Iframe failed to load within timeout'));
}, 30000);
this.iframe.addEventListener('load', () => {
clearTimeout(timeoutId);
resolve();
});
this.iframe.addEventListener('error', (e) => {
clearTimeout(timeoutId);
reject(new Error('Iframe failed to load: ' + (e as ErrorEvent).message));
});
});
🤖 Prompt for AI Agents
In
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
around lines 19 to 23, the iframeLoadedPromise never rejects if the iframe fails
to load, causing send() calls to hang; change the promise to attach both 'load'
and 'error' listeners, implement a configurable timeout that rejects the promise
if neither event fires within the deadline, and ensure listeners and the timeout
are cleaned up when one of the outcomes occurs so the promise always settles
(resolve on load, reject on error or timeout) and upstream callers can handle
failures.

Comment on lines +64 to 67
async send(type: string, payload: any): Promise<void> {
await this.iframeLoadedPromise;
this.iframe.contentWindow?.postMessage({ type, payload }, this.sandboxUrl);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that the base class signature matches or callers handle the Promise.

The logic correctly ensures messages are sent only after the iframe has loaded, which fixes the hang issue.

The method signature changed from returning void to returning Promise<void>. Please verify:


🏁 Script executed:

#!/bin/bash
# Description: Verify the base class signature and all callers of send() method

# Check base class signature
echo "=== Base class ScriptEvaluatorClient.send signature ==="
ast-grep --pattern $'class ScriptEvaluatorClient {
  $$$
  send($_, $_) {
    $$$
  }
  $$$
}'

# Find all invocations of send() on EvaluatorFrameClient or ScriptEvaluatorClient
echo -e "\n=== Callers of send() method ==="
rg -nP --type=ts -C3 '\b(evaluator|client)\.send\s*\(' -g '!**/node_modules/**'

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Show evaluator-client.factory.ts for context
echo "=== evaluator-client.factory.ts (lines 1-200) ==="
sed -n '1,200p' packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts

# Find and inspect ScriptEvaluatorClient class
echo "=== ScriptEvaluatorClient files ==="
rg -l --type ts "class ScriptEvaluatorClient" -g '!**/node_modules/**'
echo "=== Inspecting ScriptEvaluatorClient implementation ==="
for f in $(rg -l --type ts "class ScriptEvaluatorClient" -g '!**/node_modules/**'); do
  echo "--- File: $f ---"
  sed -n '1,200p' "$f"
done

# Identify any EvaluatorClient interface
echo "=== EvaluatorClient interface(s) ==="
rg -n --type ts "interface.*EvaluatorClient" -g '!**/node_modules/**'

# Find all send() invocations across the codebase
echo "=== send() callers ==="
rg -n --type ts "\.send\s*\(" -g '!**/node_modules/**' -C2

Length of output: 33664


Align send() signature with the base class
The abstract ScriptEvaluatorClient.send(type: string, payload: TODO) returns void, but EvaluatorFrameClient.send is declared async and returns Promise<void>. Either remove async (e.g. use this.iframeLoadedPromise.then(...)) so it returns void, or update the base abstract method to return Promise<void>.

🤖 Prompt for AI Agents
packages/altair-app/src/app/modules/altair/services/pre-request/evaluator-client.factory.ts
lines 64-67: the concrete send() is async and awaits iframeLoadedPromise but the
abstract ScriptEvaluatorClient.send is declared to return void; update the
abstract method signature to return Promise<void> so it matches async
implementations, then update any other subclasses/implementations to return a
Promise (adjust implementations if they were synchronous) and ensure TypeScript
types/imports compile.

@imolorhe imolorhe added this pull request to the merge queue Oct 11, 2025
Merged via the queue into master with commit d9a4bf3 Oct 11, 2025
26 checks passed
@imolorhe imolorhe deleted the imolorhe/fix-evaluator-frame-client branch October 11, 2025 22:46
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

Successfully merging this pull request may close these issues.

2 participants