o
    ,&]i=                     @  s   U d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZmZ dd
lmZ erIddlmZ ddlmZ eeZded< eG dd dZG dd dZdS )a  Custom Components v2 manager and supporting orchestration.

This module composes the registry, manifest handling, and file watching
capabilities for Streamlit's Custom Components v2. It provides a unified
interface to register components from manifests or individual definitions, query
component metadata and asset paths, and react to on-disk changes by re-resolving
component definitions.
    )annotationsN)	dataclass)TYPE_CHECKINGFinal build_definition_with_validation)ComponentFileWatcher)ComponentManifestHandler)BidiComponentDefinitionBidiComponentRegistry)
get_logger)Path)ComponentManifestr   _LOGGERc                   @  s"   e Zd ZU dZded< ded< dS )
_ApiInputsa.  Inputs provided via the Python API to resolve a component definition.

    Attributes
    ----------
    css : str | None
        Inline CSS content or a path/glob to a CSS asset within ``asset_dir``.
    js : str | None
        Inline JS content or a path/glob to a JS asset within ``asset_dir``.
    
str | NonecssjsN)__name__
__module____qualname____doc____annotations__ r   r   g/var/www/html/IGF-ODF-V3/venv/lib/python3.10/site-packages/streamlit/components/v2/component_manager.pyr   1   s   
 
r   c                   @  s   e Zd ZdZ			dDdEddZdFddZdGddZdHddZdId d!ZdJd#d$Z	dKd&d'Z
dLd(d)ZdMd*d+ZdNd,d-ZdMd.d/Zd0d1dOd4d5ZdMd6d7ZdPd:d;ZdQd>d?ZdRd@dAZedSdBdCZdS )TBidiComponentManagera9  Manager class that composes component registry, manifest handler, and
    file watcher.

    This class provides a unified interface for working with bidirectional
    components while maintaining clean separation of concerns through
    composition. It handles the coordination and lifecycle management of all
    component-related functionality.

    Component Lifecycle
    -------------------
    The lifecycle of a component managed by this class involves four key stages:

    1.  **Discovery**: On startup, ``discover_and_register_components`` scans
        for installed packages with component manifests (``pyproject.toml``).
        For each component found, a placeholder definition containing only its
        name and ``asset_dir`` is registered. This makes the system aware of all
        available installed components from the outset.

    2.  **Definition & Validation**: When a user's script calls the public API
        (e.g., ``st.components.v2.component(...)``), the manager invokes
        ``build_definition_with_validation``. This function is the single,
        centralized point for all validation. It resolves file paths, performs
        security checks against the component's ``asset_dir``, and produces a
        complete, validated ``BidiComponentDefinition``.

    3.  **Registration**: The validated definition is then passed to the
        registry's ``register`` method. This adds the complete definition,
        overwriting the placeholder if one existed from the discovery phase.

    4.  **Updating**: The ``ComponentFileWatcher`` monitors the ``asset_dir``
        for changes. On a change, it triggers a re-computation of the definition
        using the original API inputs, runs it through the same validation
        logic, and updates the registry with the new definition via the stricter
        ``update_component`` method.

    Notes
    -----
    This manager intentionally favors composition over inheritance and delegates
    specialized responsibilities to ``BidiComponentRegistry``,
    ``ComponentManifestHandler``, and ``ComponentFileWatcher``.
    NregistryBidiComponentRegistry | Nonemanifest_handlerComponentManifestHandler | Nonefile_watcherComponentFileWatcher | NonereturnNonec                 C  s<   |pt  | _|p
t | _i | _t | _|pt| j	| _
dS )a  Initialize the component manager.

        Parameters
        ----------
        registry : BidiComponentRegistry, optional
            Component registry instance. If not provided, a new one will be created.
        manifest_handler : ComponentManifestHandler, optional
            Manifest handler instance. If not provided, a new one will be created.
        file_watcher : ComponentFileWatcher, optional
            File watcher instance. If not provided, a new one will be created.
        N)r   	_registryr	   _manifest_handler_api_inputs	threadingLock_api_inputs_lockr   _on_components_changed_file_watcher)selfr   r   r    r   r   r   __init__l   s   

zBidiComponentManager.__init__component_keystrr   r   r   c                 C  s>   | j  t||d| j|< W d   dS 1 sw   Y  dS )a  Record original API inputs for later re-resolution on file changes.

        Parameters
        ----------
        component_key : str
            Fully-qualified component name.
        css : str | None
            Inline CSS or a path/glob to a CSS file within the component's
            ``asset_dir``.
        js : str | None
            Inline JavaScript or a path/glob to a JS file within the component's
            ``asset_dir``.
        )r   r   N)r)   r   r&   )r,   r.   r   r   r   r   r   record_api_inputs   s   "z&BidiComponentManager.record_api_inputsmanifestr   package_rootr   c                 C  s.   | j ||}| j| tdt| dS )a  Register components from a manifest file.

        This is a high-level method that processes the manifest and registers
        all components found within it.

        Parameters
        ----------
        manifest : ComponentManifest
            The component manifest to process.
        package_root : Path
            Root path of the package containing the components.
        z&Registered %d components from manifestN)r%   process_manifestr$   $register_components_from_definitionsr   debuglen)r,   r1   r2   component_definitionsr   r   r   register_from_manifest   s   z+BidiComponentManager.register_from_manifest
definitionr
   c                 C     | j | dS )zRegister a single component definition.

        Parameters
        ----------
        definition : BidiComponentDefinition
            The component definition to register.
        N)r$   register)r,   r9   r   r   r   r;         zBidiComponentManager.registernameBidiComponentDefinition | Nonec                 C     | j |S )a%  Get a component definition by name.

        Parameters
        ----------
        name : str
            The name of the component to retrieve.

        Returns
        -------
        BidiComponentDefinition or None
            The component definition if found; otherwise ``None``.
        )r$   getr,   r=   r   r   r   r@         zBidiComponentManager.gethtmlc                C  s   t | ||||dS )ag  Build a validated component definition for the given inputs.

        Parameters
        ----------
        component_key : str
            Fully-qualified component name the definition is for.
        html : str | None
            Inline HTML content to include in the definition.
        css : str | None
            Inline CSS content or a path/glob under the component's asset_dir.
        js : str | None
            Inline JS content or a path/glob under the component's asset_dir.

        Returns
        -------
        BidiComponentDefinition
            The fully validated component definition.
        )managerr.   rC   r   r   r   )r,   r.   rC   r   r   r   r   r   r      s   z5BidiComponentManager.build_definition_with_validationPath | Nonec                 C  r?   )aL  Get the asset root for a manifest-backed component.

        Parameters
        ----------
        name : str
            The name of the component to get the asset root for.

        Returns
        -------
        Path or None
            The component's ``asset_root`` directory if found; otherwise
            ``None``.
        )r%   get_asset_rootrA   r   r   r   get_component_asset_root   s   z-BidiComponentManager.get_component_asset_rootc                 C  r:   )zUnregister a component by name.

        Parameters
        ----------
        name : str
            The name of the component to unregister.
        N)r$   
unregisterrA   r   r   r   rH      r<   zBidiComponentManager.unregisterc                 C  s   | j   dS )z Clear all registered components.N)r$   clearr,   r   r   r   rI   
  s   zBidiComponentManager.clearc                 C  s    | j |}|durt|S dS )a5  Get the filesystem path for a manifest-backed component.

        Parameters
        ----------
        name : str
            The name of the component.

        Returns
        -------
        str or None
            The component's ``asset_dir`` directory if found; otherwise
            ``None``.
        N)r%   rF   r/   )r,   r=   
asset_rootr   r   r   get_component_path  s   z'BidiComponentManager.get_component_pathc                 C  sP   | j jrtd dS | j }| j | | j jr!td dS td dS )z*Start file watching for component changes.z File watching is already startedNz+Started file watching for component changeszFile watching not started)r+   is_watching_activer   warningr%   get_asset_watch_rootsstart_file_watchingr5   )r,   asset_rootsr   r   r   rP   "  s   

z(BidiComponentManager.start_file_watchingT)rP   rP   boolc             
   C  s   z+ddl m} | }|D ]\}}| || td|j|j q|r)|   W dS W dS  tyD } zt	d| W Y d}~dS d}~ww )an  Discover installed v2 components and register them.

        This scans installed distributions for manifests, registers all discovered
        components, and starts file watching for development workflows.

        Parameters
        ----------
        start_file_watching : bool
            Whether to start file watching after components are registered.
        r   )scan_component_manifestsz1Registered components from pyproject.toml: %s v%sz&Failed to scan component manifests: %sN)
(streamlit.components.v2.manifest_scannerrS   r8   r   r5   r=   versionrP   	ExceptionrN   )r,   rP   rS   	manifestsr1   r2   er   r   r    discover_and_register_components3  s"   z5BidiComponentManager.discover_and_register_componentsc                 C  s.   | j jstd dS | j   td dS )zStop file watching.zFile watching is not startedNzStopped file watching)r+   rM   r   rN   stop_file_watchingr5   rJ   r   r   r   rZ   U  s
   

z'BidiComponentManager.stop_file_watchingcomponent_nameComponentManifest | Nonec                 C  r?   )a)  Get metadata for a component.

        Parameters
        ----------
        component_name : str
            The name of the component to get metadata for.

        Returns
        -------
        ComponentManifest or None
            The component metadata if found; otherwise ``None``.
        )r%   get_metadata)r,   r[   r   r   r   r]   _  rB   z!BidiComponentManager.get_metadatacomponent_names	list[str]c              	   C  sN   |D ]"}z|  |}|dur| j| W q ty$   td| Y qw dS )a]  Handle change events for components' asset roots.

        For each component, re-resolve from stored API inputs and update the
        registry with the new definition if resolution succeeds.

        Parameters
        ----------
        component_names : list[str]
            Fully-qualified component names whose watched files changed.
        Nz+Failed to update component after change: %s)_recompute_definition_from_apir$   update_componentrV   r   	exception)r,   r^   r=   updated_defr   r   r   r*   n  s   
z+BidiComponentManager._on_components_changedc                 C  s   | j W | j|}|du r	 W d   dS | j|}|r"|jnd}z| j|||j|jd}W n  tyQ } zt	
d|| W Y d}~W d   dS d}~ww W d   |S 1 s]w   Y  |S )a  Recompute a component's definition using previously recorded API inputs.

        Parameters
        ----------
        component_name : str
            Fully-qualified component name to recompute.

        Returns
        -------
        BidiComponentDefinition | None
            A fully validated component definition suitable for replacing the
            stored entry in the registry, or ``None`` if recomputation failed
            or no API inputs were previously recorded.
        N)r.   rC   r   r   z5Skipping update for %s due to re-resolution error: %s)r)   r&   r@   r$   rC   r   r   r   rV   r   r5   )r,   r[   inputsexisting_def
html_valuenew_defrX   r   r   r   r`     s:   


z3BidiComponentManager._recompute_definition_from_apic                 C  s   | j jS )zCheck if file watching is currently active.

        Returns
        -------
        bool
            True if file watching is started, False otherwise
        )r+   rM   rJ   r   r   r   is_file_watching_started  s   	z-BidiComponentManager.is_file_watching_started)NNN)r   r   r   r   r    r!   r"   r#   )r.   r/   r   r   r   r   r"   r#   )r1   r   r2   r   r"   r#   )r9   r
   r"   r#   )r=   r/   r"   r>   )
r.   r/   rC   r   r   r   r   r   r"   r
   )r=   r/   r"   rE   )r=   r/   r"   r#   )r"   r#   )r=   r/   r"   r   )rP   rR   r"   r#   )r[   r/   r"   r\   )r^   r_   r"   r#   )r[   r/   r"   r>   )r"   rR   )r   r   r   r   r-   r0   r8   r;   r@   r   rG   rH   rI   rL   rP   rY   rZ   r]   r*   r`   propertyrh   r   r   r   r   r   A   s0    ,






"





"



-r   )r   
__future__r   r'   dataclassesr   typingr   r   5streamlit.components.v2.component_definition_resolverr   .streamlit.components.v2.component_file_watcherr   2streamlit.components.v2.component_manifest_handlerr	   *streamlit.components.v2.component_registryr
   r   streamlit.loggerr   pathlibr   rT   r   r   r   r   r   r   r   r   r   r   <module>   s"   	