Skip to content

Feature | Introduce window.Infiniframe to the js layer instead of window.external calls #215

@AnnaSasDev

Description

@AnnaSasDev

Problem / Motivation

HostMessaging.sendMessageToHost currently builds a string payload (id;data) and uses platform heuristics:

  • window.chrome.webview.postMessage(...)
  • window.external.sendMessage(...)

This is brittle across platforms and makes protocol + transport tightly coupled in JS.
The TODO indicates missing a unified messaging contract for InfiniFrame.NET across Windows/WebView2, BlazorWebView, and native hosts.

Goal

Define and implement a single, explicit host-bridge contract for all supported platforms, with deterministic dispatch behavior and backward compatibility during migration.

Current code (context)

public sendMessageToHost(id: SendToHostMessageId | string, data?: string) {
    const message = data ? `${id};${data}` : id;

    // TODO - determine messaging methods for InfiniFrame.NET for all platforms
    if (window.chrome?.webview) {
        window.chrome.webview.postMessage(message);
    } else if (window.external?.sendMessage) {
        ...

Source:
src/InfiniFrame.Js/TsSource/HostMessaging.ts (around line 47)

Proposed architecture

Introduce a stable JS bridge namespace and transport adapter model:

  • Public JS API: window.infiniframe.host.postMessage(envelope)
  • Envelope contract (versioned): { id, data, version, channel? }
  • Internal transport adapters detect and call platform primitives:
    • WebView2: window.chrome.webview.postMessage
    • Legacy external bridge: window.external.sendMessage
    • Additional platform hooks as needed
  • Parsing/validation enforced in JS and host sides (C#, C++)

Why window.infiniframe is the right direction

Pros:

  • Decouples app-level dispatch from host transport details.
  • Enables contract/versioning without changing caller code.
  • Reduces heuristic branching scattered across JS.

Tradeoff:

  • Requires coordinated updates in JS + C# + C++.
  • Needs compatibility layer for existing callers/protocol.

Migration strategy (required)

  1. Add window.infiniframe.host.postMessage as new primary path.
  2. Keep legacy transport/protocol fallback for migration window.
  3. Emit telemetry/log warnings when legacy path is used.
  4. Update C# and C++ host handlers to accept new envelope.
  5. Switch default writers to new contract.
  6. Remove legacy id;payload and direct caller transport branching after deprecation window.

Scope

  • InfiniFrame.Js: new bridge API, adapters, envelope serialization/validation.
  • InfiniFrame / InfiniFrame.BlazorWebView: host receive pipeline + compatibility parser.
  • InfiniFrame.Native (C++): host bridge endpoint + envelope handling.
  • Shared docs: protocol spec, versioning, migration/deprecation policy.

Acceptance criteria

  • JS callers use one API: window.infiniframe.host.postMessage(...).
  • No caller-level dependence on window.chrome / window.external.
  • Envelope validation failures do not crash dispatch flow.
  • Cross-platform tests pass for all supported hosts.
  • Legacy protocol remains functional only during migration window.
  • Deprecation logs and removal plan are documented.

Test plan

  • Unit tests (JS): adapter selection, envelope serialization, malformed input handling.
  • Unit tests (C#/C++): envelope parsing, version handling, fallback behavior.
  • Integration tests: JS -> host messaging on each supported platform.
  • Regression tests: legacy id;payload still works during migration.
  • Stress tests: startup timing/order does not break registration/dispatch.

Risks

  • Breaking interop if host and JS versions are mismatched.
  • Partial rollout across repos causing runtime incompatibility.

Mitigations

  • Versioned envelope + capability checks.
  • Compatibility parser on host side.
  • Incremental rollout with telemetry and clear cutoff version.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions