export declare const PARHELIA_EDITING_BRIDGE_FAMILY: "parhelia/editing-bridge";
export type BridgeFamily = typeof PARHELIA_EDITING_BRIDGE_FAMILY;
export type ParheliaEditingBridgeConfig = {
    editorOrigin?: string;
    parentOrigin?: string;
    parentOrigins?: string[];
    allowedParentOrigins?: string[];
    mode?: string;
    pageId?: string;
    source?: string;
};
/**
 * Protocol version. `major` is the compatibility boundary — peers must share
 * the same major to interoperate. `minor` is additive: a higher minor only
 * adds optional, backwards-compatible messages/fields and is negotiated down to
 * the lower of the two peers (see `negotiateMinor`).
 */
export type BridgeVersion = {
    major: number;
    minor: number;
};
export declare const PARHELIA_EDITING_BRIDGE_VERSION: BridgeVersion;
export type BridgeDirection = "parent-to-host" | "host-to-parent";
export type BridgeEnvelope<TName extends string = string, TPayload = unknown> = {
    family: BridgeFamily;
    version: BridgeVersion;
    direction: BridgeDirection;
    id: string;
    name: TName;
    timestamp: number;
    requestId?: string;
    payload: TPayload;
};
export type BridgeRect = {
    x: number;
    y: number;
    width: number;
    height: number;
    top: number;
    right: number;
    bottom: number;
    left: number;
};
export type BridgeViewport = {
    width: number;
    height: number;
};
export type BridgeScroll = {
    x: number;
    y: number;
};
/**
 * Capabilities are an OPEN set of string names. The editor and host each
 * advertise the names they support; the effective session set is the
 * intersection (see `negotiateCapabilities`). Unknown names are ignored by
 * older peers, so adding a capability is always a backwards-compatible (minor)
 * change. `BRIDGE_CAPABILITIES` lists the well-known names for type-safe use.
 */
export declare const BRIDGE_CAPABILITIES: {
    readonly structure: "structure";
    readonly geometry: "geometry";
    readonly selection: "selection";
    readonly inlineEditing: "inlineEditing";
    readonly richTextCommands: "richTextCommands";
    readonly captureDom: "captureDom";
    readonly refresh: "refresh";
    readonly zoom: "zoom";
    readonly pointerDrag: "pointerDrag";
    readonly dragPreview: "dragPreview";
};
export type WellKnownBridgeCapability = (typeof BRIDGE_CAPABILITIES)[keyof typeof BRIDGE_CAPABILITIES];
export type BridgeCapability = WellKnownBridgeCapability | (string & {});
export type BridgeCapabilitySet = BridgeCapability[];
export type BridgeRuntimeSource = "alpaca" | "sxa" | "sitecore" | "internal" | (string & {});
/** Identifying metadata the host attaches to `ready` to aid debugging. */
export type BridgeRuntimeInfo = {
    source?: BridgeRuntimeSource;
    packageVersion?: string;
    commit?: string;
    builtAt?: string;
};
export type BridgeItemDescriptor = {
    id: string;
    language?: string;
    version?: number;
    name?: string;
    displayName?: string;
    path?: string;
    database?: string;
};
export type SerializableRenderedItem = BridgeItemDescriptor & {
    renderedFieldIds: string[];
};
export type SerializableField = {
    elementKey: string;
    fieldId: string;
    item?: BridgeItemDescriptor;
    componentId?: string;
    textContent?: string;
    isRichText?: boolean;
    editable?: boolean;
};
export type SerializablePlaceholder = {
    key: string;
    name?: string;
    elementKey?: string;
    parentComponentId?: string;
    componentIds: string[];
    editable?: boolean;
};
export type SerializableComponent = {
    id: string;
    elementKey: string;
    endElementKey?: string;
    name?: string;
    type?: string;
    typeId?: string;
    placeholderKey?: string;
    parentComponentId?: string;
    datasourceItem?: SerializableRenderedItem;
    items: SerializableRenderedItem[];
    placeholders: string[];
    renderedDictionaryKeys: string[];
    editorFields?: Record<string, {
        addFields: string[];
        removeFields: string[];
    }>;
    editable?: boolean;
    visible?: boolean;
};
export type SerializablePageStructure = {
    editRevision?: string;
    pageId?: string;
    url: string;
    components: SerializableComponent[];
    placeholders: SerializablePlaceholder[];
    fields: SerializableField[];
};
export type SerializableComponentSkeleton = {
    id: string;
    name: string;
    type: string;
    typeId: string;
    parametersTemplateId?: string;
    parameters?: string;
    items: SerializableRenderedItem[];
    placeholders: SerializablePlaceholderSkeleton[];
    datasourceItem?: SerializableRenderedItem;
    isRemovedFromMasterLanguage?: boolean;
    isInheritedFromMasterLanguage?: boolean;
    visible?: boolean;
    renderedDictionaryKeys: string[];
    isShared?: boolean;
    hasPersonalization?: boolean;
    layoutId?: string;
    isSharedLayout?: boolean;
    editorFields: Record<string, {
        addFields: string[];
        removeFields: string[];
    }>;
    editable?: boolean;
};
export type SerializablePlaceholderSkeleton = {
    name: string;
    key: string;
    description: string;
    components: SerializableComponentSkeleton[];
    editable?: boolean;
};
export type SerializablePageSkeleton = {
    editRevision: string;
    item: SerializableRenderedItem;
    rootComponent: SerializableComponentSkeleton;
};
export type BridgeGeometryTargetKind = "component" | "placeholder" | "field" | "textRange" | "dropTarget";
export type BridgeGeometryTarget = {
    kind: BridgeGeometryTargetKind;
    key: string;
    elementKey?: string;
    componentId?: string;
    placeholderKey?: string;
    fieldId?: string;
    item?: BridgeItemDescriptor;
    orientation?: "horizontal" | "vertical";
    description?: string;
    rect: BridgeRect;
};
export type BridgeGeometrySnapshot = {
    viewport: BridgeViewport;
    scroll: BridgeScroll;
    devicePixelRatio: number;
    rectScale?: number;
    scrollScale?: number;
    targets: BridgeGeometryTarget[];
};
export type BridgeSelectionSnapshot = {
    activeField?: {
        elementKey: string;
        fieldId: string;
        item?: BridgeItemDescriptor;
        isRichText?: boolean;
    };
    collapsed: boolean;
    rect?: BridgeRect;
    startOffset?: number;
    endOffset?: number;
    text?: string;
    formatting?: BridgeSelectionFormattingState;
    metadata?: Record<string, unknown>;
};
export type BridgeSelectionFormattingState = {
    bold?: boolean;
    italic?: boolean;
    underline?: boolean;
    strikethrough?: boolean;
    subscript?: boolean;
    superscript?: boolean;
    link?: boolean;
    orderedList?: boolean;
    unorderedList?: boolean;
    blockTag?: string;
};
export type BridgeMediaTarget = {
    elementKey: string;
    tagName: "img" | "picture" | "source" | string;
    variantName?: string;
};
export type ReadyEventPayload = {
    version: BridgeVersion;
    hostUrl: string;
    pageId?: string;
    mode?: string;
    viewport: BridgeViewport;
    scroll: BridgeScroll;
    devicePixelRatio: number;
    capabilities: BridgeCapabilitySet;
    runtime?: BridgeRuntimeInfo;
};
export type StructureUpdatedEventPayload = {
    structure: SerializablePageStructure;
};
export type PageSkeletonUpdatedEventPayload = {
    pageSkeleton: SerializablePageSkeleton;
};
export type GeometryUpdatedEventPayload = {
    geometry: BridgeGeometrySnapshot;
};
export type ScrollChangedEventPayload = {
    scroll: BridgeScroll;
};
export type ResizeChangedEventPayload = {
    viewport: BridgeViewport;
    devicePixelRatio: number;
};
export type InteractionEventPayload = {
    kind: "click" | "doubleClick" | "contextMenu" | "hover" | "dragIntent" | "keydown" | "wheel";
    elementKey?: string;
    componentId?: string;
    fieldId?: string;
    item?: BridgeItemDescriptor;
    media?: BridgeMediaTarget;
    placeholderKey?: string;
    clientX?: number;
    clientY?: number;
    selectionRect?: BridgeRect;
    caretRect?: BridgeRect;
    key?: string;
    code?: string;
    button?: number;
    deltaX?: number;
    deltaY?: number;
    ctrlKey?: boolean;
    shiftKey?: boolean;
    altKey?: boolean;
    metaKey?: boolean;
    selectedText?: string;
    selectionStartOffset?: number;
    selectionEndOffset?: number;
};
export type SelectionChangedEventPayload = {
    selection: BridgeSelectionSnapshot;
};
export type FieldValueChangedEventPayload = {
    elementKey: string;
    fieldId: string;
    item?: BridgeItemDescriptor;
    value: string;
    isRichText?: boolean;
};
export type InlineEditEndedEventPayload = {
    elementKey: string;
    fieldId: string;
    item?: BridgeItemDescriptor;
    value: string;
    isRichText?: boolean;
    reason: "blur" | "commit" | "cancel";
};
export type RefreshStartedEventPayload = {
    revision?: string;
};
export type RefreshCompletedEventPayload = {
    revision?: string;
    structure?: SerializablePageStructure;
    geometry?: BridgeGeometrySnapshot;
};
export type RenderErrorEventPayload = {
    message: string;
    code?: string;
    details?: unknown;
};
export type DomUpdatedEventPayload = {
    html: string;
    url: string;
    viewport: BridgeViewport;
    scroll: BridgeScroll;
    scrollWidth: number;
    scrollHeight: number;
};
export type CaptureDomResultEventPayload = {
    requestId: string;
    html?: string;
    text?: string;
    error?: string;
};
export type DragGestureStartedEventPayload = {
    pointerId: number;
    elementKey: string;
    componentId?: string;
    clientX: number;
    clientY: number;
};
export type DragGestureMovedEventPayload = {
    pointerId: number;
    clientX: number;
    clientY: number;
};
export type DragGestureEndedEventPayload = {
    pointerId: number;
    clientX: number;
    clientY: number;
    /** True when the gesture was aborted (Escape / pointercancel) rather than dropped. */
    canceled?: boolean;
};
export type DragSnapshotEventPayload = {
    elementKey: string;
    /** Data URL (JPEG/PNG) of the dragged element, captured host-side. */
    dataUrl: string;
    width: number;
    height: number;
};
export type BridgeEventPayloadByName = {
    ready: ReadyEventPayload;
    structureUpdated: StructureUpdatedEventPayload;
    pageSkeletonUpdated: PageSkeletonUpdatedEventPayload;
    geometryUpdated: GeometryUpdatedEventPayload;
    scrollChanged: ScrollChangedEventPayload;
    resizeChanged: ResizeChangedEventPayload;
    interaction: InteractionEventPayload;
    selectionChanged: SelectionChangedEventPayload;
    fieldValueChanged: FieldValueChangedEventPayload;
    inlineEditEnded: InlineEditEndedEventPayload;
    refreshStarted: RefreshStartedEventPayload;
    refreshCompleted: RefreshCompletedEventPayload;
    renderError: RenderErrorEventPayload;
    domUpdated: DomUpdatedEventPayload;
    captureDomResult: CaptureDomResultEventPayload;
    dragGestureStarted: DragGestureStartedEventPayload;
    dragGestureMoved: DragGestureMovedEventPayload;
    dragGestureEnded: DragGestureEndedEventPayload;
    dragSnapshot: DragSnapshotEventPayload;
};
export type BridgeEventName = keyof BridgeEventPayloadByName;
export type BridgeEvent<TName extends BridgeEventName = BridgeEventName> = TName extends BridgeEventName ? BridgeEnvelope<TName, BridgeEventPayloadByName[TName]> & {
    direction: "host-to-parent";
} : never;
export type HelloCommandPayload = {
    /** The editor's protocol version, advertised on (re)connect. */
    version?: BridgeVersion;
};
export type InitCommandPayload = {
    editorOrigin: string;
    sessionId?: string;
    signedContext?: string;
    mode: "edit" | "preview" | "suggestions" | string;
    suggestionsCursorActive?: boolean;
    selectedComponentIds: string[];
    featureFlags?: Record<string, boolean>;
    /** The editor's protocol version, so the host can record/negotiate. */
    version?: BridgeVersion;
    /**
     * Capabilities the editor acknowledges for this session: the intersection of
     * what the host advertised in `ready` and what the editor supports. The host
     * should only run/advertise behaviors in this set. `init` is the handshake
     * boundary — the host should wait for it before emitting operational events.
     */
    acknowledgedCapabilities?: BridgeCapabilitySet;
};
export type RefreshCommandPayload = {
    url?: string;
    revision?: string;
    route?: string;
    layoutKind?: "final" | "shared" | string;
};
export type SetSelectionCommandPayload = {
    componentIds?: string[];
    field?: {
        elementKey?: string;
        fieldId?: string;
    };
    placeholderKey?: string;
};
export type ScrollIntoViewCommandPayload = {
    elementKey?: string;
    componentId?: string;
    fieldId?: string;
    placeholderKey?: string;
    block?: "start" | "center" | "end" | "nearest";
};
export type ScrollByCommandPayload = {
    x?: number;
    y?: number;
    behavior?: "auto" | "instant" | "smooth";
};
export type QueryGeometryCommandPayload = {
    keys?: string[];
    textRanges?: Array<{
        key: string;
        elementKey?: string;
        fieldId?: string;
        item?: BridgeItemDescriptor;
        start: number;
        end: number;
    }>;
};
export type BeginInlineEditCommandPayload = {
    elementKey: string;
    fieldId: string;
    clientX?: number;
    clientY?: number;
    selectedText?: string;
    selectionStartOffset?: number;
    selectionEndOffset?: number;
};
export type ApplyFieldPatchCommandPayload = {
    elementKey: string;
    fieldId: string;
    value: string;
    isRichText?: boolean;
    source?: "real" | "suggestion-preview" | "reset" | string;
};
export type ApplyRichTextCommandPayload = {
    elementKey: string;
    fieldId: string;
    command: string;
    value?: string;
    selectedText?: string;
    selectionStartOffset?: number;
    selectionEndOffset?: number;
};
export type TextCompletionCommandPayload = {
    elementKey: string;
    fieldId: string;
    action: "show" | "apply" | "clear";
    completion?: string;
    selectedText?: string;
    selectionStartOffset?: number;
    selectionEndOffset?: number;
};
export type CommitInlineEditCommandPayload = {
    elementKey: string;
    fieldId: string;
};
export type CancelInlineEditCommandPayload = {
    elementKey: string;
    fieldId: string;
    forceReadOnly?: boolean;
};
export type SetPreviewModeCommandPayload = {
    enabled: boolean;
};
export type SetEditorModeCommandPayload = {
    mode: "edit" | "preview" | "suggestions";
    suggestionsCursorActive?: boolean;
};
export type SetLayoutKindCommandPayload = {
    layoutKind: "final" | "shared" | string;
};
export type SetChromeVisibilityCommandPayload = {
    visible: boolean;
};
export type SetZoomCommandPayload = {
    zoom: number;
};
export type CaptureDomCommandPayload = {
    requestId: string;
    selector?: string;
    includeText?: boolean;
};
export type PreviewGapCommandPayload = {
    siblingElementKeys: Array<string | null>;
    fromDomIndex: number;
    gapPx: number;
    axis: "x" | "y";
    movingElementKey?: string;
} | {
    clear: true;
};
export type CaptureComponentSnapshotCommandPayload = {
    elementKey: string;
};
export type BridgeCommandPayloadByName = {
    hello: HelloCommandPayload;
    init: InitCommandPayload;
    refresh: RefreshCommandPayload;
    setSelection: SetSelectionCommandPayload;
    scrollIntoView: ScrollIntoViewCommandPayload;
    scrollBy: ScrollByCommandPayload;
    queryGeometry: QueryGeometryCommandPayload;
    beginInlineEdit: BeginInlineEditCommandPayload;
    applyFieldPatch: ApplyFieldPatchCommandPayload;
    applyRichTextCommand: ApplyRichTextCommandPayload;
    textCompletion: TextCompletionCommandPayload;
    commitInlineEdit: CommitInlineEditCommandPayload;
    cancelInlineEdit: CancelInlineEditCommandPayload;
    setPreviewMode: SetPreviewModeCommandPayload;
    setEditorMode: SetEditorModeCommandPayload;
    setLayoutKind: SetLayoutKindCommandPayload;
    setChromeVisibility: SetChromeVisibilityCommandPayload;
    setZoom: SetZoomCommandPayload;
    captureDom: CaptureDomCommandPayload;
    previewGap: PreviewGapCommandPayload;
    captureComponentSnapshot: CaptureComponentSnapshotCommandPayload;
};
export type BridgeCommandName = keyof BridgeCommandPayloadByName;
export type BridgeCommand<TName extends BridgeCommandName = BridgeCommandName> = TName extends BridgeCommandName ? BridgeEnvelope<TName, BridgeCommandPayloadByName[TName]> & {
    direction: "parent-to-host";
} : never;
export declare function isKnownBridgeCommandName(value: unknown): value is BridgeCommandName;
export declare function isKnownBridgeEventName(value: unknown): value is BridgeEventName;
export declare function createBridgeEnvelope<TName extends BridgeCommandName, TPayload extends BridgeCommandPayloadByName[TName]>(name: TName, payload: TPayload, options?: {
    id?: string;
    timestamp?: number;
    requestId?: string;
}): BridgeCommand<TName>;
export declare function createBridgeEnvelope<TName extends BridgeEventName, TPayload extends BridgeEventPayloadByName[TName]>(name: TName, payload: TPayload, options: {
    direction: "host-to-parent";
    id?: string;
    timestamp?: number;
    requestId?: string;
}): BridgeEvent<TName>;
export declare function isBridgeEnvelope(value: unknown): value is BridgeEnvelope;
export declare function isBridgeVersion(value: unknown): value is BridgeVersion;
/** Compatible when the major version matches; minor differences are additive. */
export declare function isCompatibleBridgeVersion(peerVersion: unknown): boolean;
/** The effective minor for a session is the lower of the two peers' minors. */
export declare function negotiateMinor(peerVersion: BridgeVersion): number;
export declare function formatBridgeVersion(value: unknown): string;
/** Intersection of two capability sets, preserving the order of the first. */
export declare function negotiateCapabilities(editorSupported: readonly BridgeCapability[], hostAdvertised: readonly BridgeCapability[]): BridgeCapability[];
/**
 * Recognition-only guard: a well-formed bridge envelope from the host,
 * regardless of whether the event name is known. RECOGNIZE messages with this;
 * DISPATCH them with `isKnownBridgeEventName` separately, so that unknown (e.g.
 * newer) events surface in diagnostics instead of being silently dropped.
 */
export declare function isBridgeMessageFromHost(value: unknown): value is BridgeEnvelope & {
    direction: "host-to-parent";
};
/** Recognition-only guard: a well-formed bridge envelope from the parent. */
export declare function isBridgeMessageFromParent(value: unknown): value is BridgeEnvelope & {
    direction: "parent-to-host";
};
export declare function isBridgeCommandEnvelope(value: unknown): value is BridgeCommand;
export declare function isBridgeEventEnvelope(value: unknown): value is BridgeEvent;
export declare function normalizeOrigin(value: string): string | undefined;
export declare function isAllowedOrigin(origin: string, allowedOrigins: readonly string[]): boolean;
export declare function assertAllowedOrigin(origin: string, allowedOrigins: readonly string[]): void;
