Surface API

The /surface entry point defines the contract between an isolated webview contribution and The AI Platform. It does not mount a framework for you.

Mount Contract

Export a mount function that accepts an HTMLElement and TapFederatedSurfaceMountContext, then returns a TapFederatedSurfaceMount cleanup handle.

import type {
  TapFederatedSurfaceMount,
  TapFederatedSurfaceMountContext,
} from '@theaiplatform/miniapp-sdk/surface';

export function mount(
  container: HTMLElement,
  context: TapFederatedSurfaceMountContext,
): TapFederatedSurfaceMount {
  container.textContent = `Release: ${context.releaseId}`;
  return {
    unmount() {
      container.replaceChildren();
    },
  };
}

The context identifies the package, release, installation, contribution, instance, and host origin. Optional workspace, channel, and conversation IDs appear only when the contribution's declared scope provides them.

Make unmount idempotent. Remove event listeners, subscriptions, timers, framework roots, and rendered content, and settle or ignore work that finishes after cleanup.

Package Events

TapPackageEventPublisher exposes publish and subscribe for the declared package event channel. subscribe returns a cleanup function; call it during unmount. Event access does not confer channel, project, or navigation authority.

const stop = context.events.subscribe('selection.changed', (payload) => {
  renderSelection(payload);
});

await context.events.publish('surface.ready', { version: 1 });
// Call stop() during unmount.

Host Authority

TapFederatedSurfaceHostAuthority exposes a boolean snapshot and a subscription. A candidate frame can start without authority, so wait for getSnapshot() to become true before performing host-backed effects.

Authority can be revoked while the surface remains mounted. Disable protected actions promptly and keep cleanup available regardless of the current snapshot.

const renderAuthority = () => {
  submitButton.disabled = !context.hostAuthority.getSnapshot();
};
renderAuthority();
const stopAuthority = context.hostAuthority.subscribe(renderAuthority);
// Call stopAuthority() during unmount.

Package Assets

resolvePackageAssetUrl joins a canonical relative path to context.packageAssetBaseUrl and returns a URL that remains inside the descriptor-selected target directory.

import { resolvePackageAssetUrl } from '@theaiplatform/miniapp-sdk/surface';

const iconUrl = resolvePackageAssetUrl(context, 'assets/icon.svg');
image.src = iconUrl.href;

Absolute paths, traversal segments, encoded separators, credentials, query strings, fragments, control characters, and non-HTTP package bases fail closed. Keep assets in the emitted target graph so integrity and portability checks can cover them.

Public Export Contract

ExportPurposeInputs and resultLifecycle and errorsWorking example
TapPackageEventPublisherPublishes and subscribes to package-declared events.publish takes a name and record; subscribe takes a listener and returns cleanup.Events outside the descriptor reject; remove every subscription during unmount.Package events
TapFederatedSurfaceHostAuthorityExposes current host authority for the exact surface realm.getSnapshot returns a boolean and subscribe returns cleanup.Authority can begin false and change while mounted; subscribers must clean up.Host authority
TapFederatedSurfaceMountContextSupplies package, release, instance, scope, event, and authority context.The host passes one immutable context to the exported mount function.Optional scope fields can be absent; do not retain context after unmount.Mount contract
TapFederatedSurfaceMountDefines the cleanup handle returned from mount.Contains an unmount function returning void or a promise.Cleanup must be idempotent and must settle all surface-owned resources.Mount contract
resolvePackageAssetUrlResolves an integrity-covered package-relative asset URL.Accepts mount context and a relative path; returns a same-target URL.Invalid bases, traversal, encoded separators, and URL decorations throw.Package assets