@mochabug/adapt-web
Version:
Browser client library for Adapt automation platform
271 lines (270 loc) • 10.1 kB
TypeScript
import { configure, resetConfig } from "@mochabug/adapt-core";
import { createConnectClient } from "@mochabug/adapt-core/connect";
import { IframePanelComponent, type IframePanelHost } from "./panel-setup.js";
import { type AdaptTheme } from "./theme.js";
import type { AdaptWebClientOptions } from "./types.js";
export type { AdaptError, AdaptErrorKind, AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemChallengeOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "./types.js";
export { resolveTheme } from "./theme.js";
export type { SignalData } from "@mochabug/adapt-core";
export { createConnectClient };
export { configure, resetConfig };
export { AdaptAutomationElement } from "./AdaptAutomationElement.js";
export { FloatingToolbar, ForkGroupActions, IframePanelComponent, MinimizeManager, } from "./panel-setup.js";
export { PanelManager, type DockPosition, type SerializedFloatingGroup, type SerializedLayoutNode, type SerializedPanelLayout, } from "./panel-manager.js";
export interface AdaptResizeMessage {
type: "adapt-resize";
width: number;
height: number;
}
export interface AdaptDarkModeMessage {
type: "adapt-darkMode";
darkMode: boolean;
}
export interface AdaptAutoResizingMessage {
type: "adapt-autoResizing";
autoResizing: boolean;
}
export interface AdaptInitMessage {
type: "adapt-init";
resize: boolean;
}
/**
* Clear persisted session state for a given automation ID.
* Use this to force a fresh session on next page load.
*
* @param automationId - The automation ID whose state to clear
* @param storage - Which storage to clear: 'session' (default), 'local', or 'both'
* @param persistKey - Custom persist key (if set via PersistOptions.key). When provided, used instead of automationId for the storage key.
*/
export declare function clearPersistedState(automationId: string, storage?: "session" | "local" | "both", persistKey?: string): void;
/**
* Browser client for rendering Adapt automation sessions.
*
* Architecture:
* - Main iframe lives in a locked group with hidden header
* - Each fork becomes a tab in the fork group
* - Side-by-side mode: fork group docked to the right of main
* - Dialog mode: fork group as a floating group
*/
export declare class AdaptWebClient implements IframePanelHost {
private static _capWidgetClass;
static registerCapWidget(cls: typeof AdaptWebClient._capWidgetClass): void;
private container;
private rootElement;
private client;
private panelManager;
private mainUrl;
private mainToken;
private options;
private sessionToken;
private forks;
private mainRetentionPolicy;
private mainCloseTimer;
private components;
private darkMode;
private autoResizing;
private forkDisplay;
private allowFloating;
private allowDocking;
private allowDialogDocking;
private allowMinimize;
private allowMaximize;
private floatingAutoResize;
/** Overlays that have already been auto-resized once (init only, no continuous resize). */
private floatingAutoResized;
private confirmOnClose;
private theme;
private _appliedThemeVars;
private beforeUnloadHandler;
private resizeObserver;
private _autoMaximizedByResize;
/** Read --mb-adapt-responsive-breakpoint from the root element, falling back to default. */
private get responsiveBreakpoint();
/** Read --mb-adapt-responsive-hysteresis from the root element, falling back to default. */
private get responsiveHysteresis();
private debug;
private destroyed;
private sessionTerminated;
private removingPanelProgrammatically;
private restoringSession;
private lastForkActive;
private sessionExpiresAt;
private messageHandler;
private minimizedTabsContainer;
private lastReportedContentHeight;
private forkPanelHeights;
private statusMessageElement;
private capWidgetInstance;
private minimizeManager;
private forkGroupActions;
private floatingToolbars;
private log;
constructor(options: AdaptWebClientOptions);
onComponentCreated(panelId: string, component: IframePanelComponent): void;
onComponentDisposed(panelId: string): void;
getDarkMode(): boolean;
getClassNames(): {
iframe?: string;
} | undefined;
private createPanelManager;
private getOrigin;
private isValidMessageOrigin;
private findComponentBySource;
private setupMessageListener;
private postToComponent;
/**
* Set dark mode state and notify all iframes.
*/
setDarkMode(darkMode: boolean): void;
/**
* Set the theme. Applies CSS custom properties derived from semantic tokens.
* Pass `undefined` to clear all theme overrides.
*/
setTheme(theme: AdaptTheme | undefined): void;
private clearThemeVars;
private applyTheme;
/**
* Enable or disable auto-resizing based on iframe content height.
*/
setAutoResizing(autoResizing: boolean): void;
/**
* Enable or disable user-initiated floating at runtime.
*/
setAllowFloating(allow: boolean): void;
/**
* Enable or disable user-initiated docking at runtime.
*/
setAllowDocking(allow: boolean): void;
/**
* Enable or disable splits inside floating dialog overlays at runtime.
*/
setAllowDialogDocking(allow: boolean): void;
/**
* Enable or disable user-initiated minimizing at runtime.
*/
setAllowMinimize(allow: boolean): void;
/**
* Enable or disable user-initiated maximizing at runtime.
*/
setAllowMaximize(allow: boolean): void;
/**
* Enable or disable floating auto-resize from iframe content at runtime.
*/
setFloatingAutoResize(enabled: boolean): void;
/** Get all non-main groups (fork groups, drag-created groups, docked groups). */
private getAllForkGroups;
/**
* Set root height = iframe content height + any chrome (minimized bar).
*/
private applyAutoResizeHeight;
/**
* Compute the best auto-resize height from all visible docked panels.
* Uses max() so the tallest visible panel determines root container height.
* When a fork is maximized the main is hidden, so only the fork contributes.
*/
private applyBestAutoResizeHeight;
/**
* Re-apply auto-resize height after chrome/layout changes.
*/
private reapplyAutoResizeHeight;
/**
* Switch between side-by-side and dialog display modes at runtime.
*/
setForkDisplayMode(mode: "side-by-side" | "dialog"): void;
private createRootElement;
private onUrl;
private handleMainUrl;
private handleForkUrl;
private ensureForkGroup;
private setupForkGroupActions;
/**
* Ensure the overlay containing this group has a FloatingToolbar
* and subscribe this group's panel-count changes to update totalTabCount.
*
* Works for both overlay owners and groups inside an internal split.
*/
/**
* Re-send adapt-autoResizing to all panels in a group based on its current location.
* Called when a group transitions between floating and docked.
*/
private updateAutoResizeForGroup;
private setupFloatingToolbar;
private resolveRetention;
private findRecyclablePanel;
private handleMainDone;
private scheduleForkClose;
private scheduleMainClose;
private restoreFork;
/**
* Create all docked groups referenced in the serialized tree,
* then rebuild the entire split tree from scratch using
* rebuildDockedLayout (which correctly handles ANY tree topology).
*/
private restoreDockedLayout;
/** Recursively create PanelGroups for every leaf in the serialized tree. */
private createGroupsFromTree;
/** Remove all fork panels and their group. */
private clearAllForks;
private rebuildForkGroup;
private handleSessionComplete;
private handleDoneMessage;
private handleStoppedMessage;
/** Remove the fork group if it exists and is empty. Safe to call multiple times. */
/**
* Clean up tracking maps for a group that no longer exists.
* Removes stale entries from forkGroupActions, floatingToolbars,
* floatingAutoResized, and minimizeManager.
*/
private cleanupGroupTracking;
/**
* Scan all tracked group IDs and clean up any that no longer exist
* in the panel manager. Catches leaks from any removal path.
*/
private cleanupStaleGroupTracking;
private removeForkGroupIfEmpty;
/**
* Find the group ID of the currently maximized docked group (if any).
* Checks all ForkGroupActions instances for isMaximized state.
*/
private getMaximizedDockedGroupId;
private emitForkActive;
private parseInheritToken;
private parseFromHash;
private parseFromParam;
private init;
private showCapWidgetAndSolve;
private resolvePersistOptions;
private getStorageKey;
private getStorage;
private saveState;
private loadState;
private clearState;
private tryRestoreSession;
/**
* Clear persisted state, stop current session, and reinitialize fresh.
*/
newSession(): Promise<void>;
/**
* Resize a floating overlay to fit the currently active panel's reported height.
* For overlays with internal splits (multiple groups), uses the maximum height
* across all active panels.
*/
private resizeOverlayForGroup;
private onContainerResize;
setConfirmOnClose(enabled: boolean): void;
private updateBeforeUnloadGuard;
private wireBeforeTabClose;
/**
* Confirm before closing all panels in a group.
* Returns true immediately if confirmOnClose is off or all forks are completed.
*/
private confirmCloseGroup;
private showConfirmDialog;
destroy(): Promise<void>;
private showStatusMessage;
private removeStatusMessage;
private showErrorStatus;
private isExpiredTokenError;
private getErrorMessage;
private classifyError;
}