import { Component } from "../../../lib";
import { TPoint } from "../../../utils/types/shapes";
export declare const IS_PORT_TYPE: "Port";
export type TPortId = string | number | symbol;
/**
 * Port data structure
 * Represents a connection point that can be attached to blocks, anchors, or custom components
 */
export type TPort<T = unknown> = {
    /** Unique identifier for the port */
    id: TPortId;
    /** X coordinate of the port */
    x: number;
    /** Y coordinate of the port */
    y: number;
    /** Component that owns this port (block, anchor, etc.) */
    component?: Component;
    /** Whether the port is waiting for position data from its component */
    lookup?: boolean;
    /** Arbitrary metadata (port doesn't know what's inside) */
    meta?: T;
};
/**
 * PortState - Reactive state container for a connection port
 *
 * Manages the lifecycle and state of a port, including position updates,
 * component ownership, and listener management for connections that use this port.
 *
 * ## Key Concepts:
 *
 * ### Lazy Creation
 * Ports are created on-demand when connections need them, even if the target
 * component doesn't exist yet. This solves initialization order problems.
 *
 * ### Lookup State
 * When `lookup: true`, the port is waiting for its component to provide coordinates.
 * When `lookup: false`, the port has valid coordinates and can be used for rendering.
 *
 * ### Listener Management
 * Tracks which components are listening to this port's changes. When no listeners
 * remain and no component owns the port, it can be safely garbage collected.
 */
export declare class PortState<T = unknown> {
    $state: import("@preact/signals-core").Signal<TPort<T>>;
    owner?: Component;
    private $delegate;
    private savedPoint;
    /**
     * Set of references observing this port's changes
     *
     * Used for reference counting to determine when the port can be safely deleted.
     * Stores actual object references to ensure accurate counting and prevent duplicates.
     */
    observers: Set<unknown>;
    /**
     * Get the port's unique identifier
     *
     * @returns {TPortId} The port's ID
     */
    get id(): TPortId;
    /**
     * Get the port's effective X coordinate (respects delegation)
     *
     * @returns {number} The X coordinate
     */
    get x(): number;
    /**
     * Get the port's effective Y coordinate (respects delegation)
     *
     * @returns {number} The Y coordinate
     */
    get y(): number;
    /**
     * Get the component that owns this port
     *
     * @returns {Component | undefined} The owning component, if any
     */
    get component(): Component | undefined;
    $point: any;
    /**
     * Get whether the port is in lookup state (waiting for coordinates)
     *
     * @returns {boolean | undefined} True if waiting for coordinates, false if resolved
     */
    get lookup(): boolean | undefined;
    /**
     * Get the port's metadata
     *
     * @returns {T | undefined} The metadata attached to this port
     */
    get meta(): T | undefined;
    constructor(port: TPort<T>);
    /**
     * Set the component that owns this port
     * @param owner Component that will own this port (block, anchor, etc.)
     * @returns void
     */
    setOwner(owner: Component): void;
    /**
     * Remove the current owner from this port
     */
    removeOwner(): void;
    /**
     * Add an observer reference to this port
     * Stores the actual reference for accurate counting
     * @param observer The object observing this port
     */
    addObserver(observer: unknown): void;
    /**
     * Remove an observer reference from this port
     * Removes the actual reference from the set
     * @param observer The object to stop observing this port
     */
    removeObserver(observer: unknown): void;
    /**
     * Update the port's position coordinates.
     * When delegated, the position is saved but does not affect getPoint() —
     * the effective position comes from the delegate port.
     * @param x New X coordinate
     * @param y New Y coordinate
     */
    setPoint(x: number, y: number): void;
    getPoint(): TPoint;
    /**
     * Delegate this port to mirror another port's position.
     * While delegated, getPoint() returns the target port's position.
     * Any setPoint() calls are saved and restored on undelegate().
     * @param target The port to mirror
     */
    delegate(target: PortState): void;
    /**
     * Remove delegation and restore the last saved position.
     * If setPoint() was called during delegation, the last value is used.
     * Otherwise, the position from before delegation is restored.
     */
    undelegate(): void;
    /**
     * Whether this port is currently delegated to another port
     */
    get isDelegated(): boolean;
    /**
     * Update port state with partial data
     * @param port Partial port data to merge with current state
     */
    updatePort(port: Partial<TPort<T>>): void;
    /**
     * Check if this port can be safely deleted
     * @returns true if port has no owner and no observers
     */
    canBeDeleted(): boolean;
}
