
    g6&                    x    d dl mZ d dlmZmZmZ d dlmZ erd dlm	Z	  G d d      Z
ddZddZ	 	 	 	 	 	 dd	Zy
)    )annotations)TYPE_CHECKINGAnyCallable)
ForwardMsg)Deltac                      e Zd ZU dZdZded<   e	 	 	 	 dd       Zd ZddZ	ddZ
dd	Z	 	 d	 	 	 	 	 dd
ZddZddZy)ForwardMsgQueuea:  Accumulates a session's outgoing ForwardMsgs.

    Each AppSession adds messages to its queue, and the Server periodically
    flushes all session queues and delivers their messages to the appropriate
    clients.

    ForwardMsgQueue is not thread-safe - a queue should only be used from
    a single thread.
    N#Callable[[ForwardMsg], None] | None_before_enqueue_msgc                    | t         _        y)zjSet a callback to be called before a message is enqueued.
        Used in static streamlit app generation.N)r
   r   )before_enqueue_msgs    X/var/www/openai/venv/lib/python3.12/site-packages/streamlit/runtime/forward_msg_queue.pyon_before_enqueue_msgz%ForwardMsgQueue.on_before_enqueue_msg&   s     /A+    c                     g | _         i | _        y N)_queue_delta_index_mapselfs    r   __init__zForwardMsgQueue.__init__.   s    (* =?r   c                    ddl m} | j                  D cg c]
  } ||       c}t        | j                  j                               dS c c}w )Nr   )MessageToDict)queueids)google.protobuf.json_formatr   r   listr   keys)r   r   ms      r   	get_debugzForwardMsgQueue.get_debug7   sF    = 15<1mA&<--2245
 	
<s   Ac                2    t        | j                        dk(  S )Nr   lenr   r   s    r   is_emptyzForwardMsgQueue.is_empty?   s    4;;1$$r   c                   t         j                  rt         j                  |       t        |      s| j                  j	                  |       yt        |j                  j                        }|| j                  v r| j                  |   }| j                  |   }t        |j                  |j                        }|Zt               }|j                  j                  |       |j                  j                  |j                         || j                  |<   yt        | j                        | j                  |<   | j                  j	                  |       y)zCAdd message into queue, possibly composing it with another message.N)r
   r   _is_composable_messager   appendtuplemetadata
delta_pathr   _maybe_compose_deltasdeltar   CopyFromr$   )r   msg	delta_keyindexold_msgcomposed_deltanew_msgs          r   enqueuezForwardMsgQueue.enqueueB   s    ..//4%c*KKs# #,,112	---)))4Ekk%(G27==#))LN)$,&&~6  ))#,,7%,E" ,/t{{+;i(3r   c                J   |sg | _         i | _        y| j                   D cg c]k  }|j                  d      dv sH|T|j                  :|j                  <|j                  j                  |j                  j                  |vrt	        ||du      m c}| _         i | _        yc c}w )a  Clear the queue, potentially retaining lifecycle messages.

        The retain_lifecycle_msgs argument exists because in some cases (in particular
        when a currently running script is interrupted by a new BackMsg), we don't want
        to remove certain messages from the queue as doing so may cause the client to
        not hear about important script lifecycle events (such as the script being
        stopped early in order to be rerun).

        If fragment_ids_this_run is provided, delta messages not belonging to any
        fragment or belonging to a fragment not in fragment_ids_this_run will be
        preserved to prevent clearing messages unrelated to the running fragments.
        type>   new_sessionparent_messagescript_finishedsession_status_changedN)r   
WhichOneofr-   fragment_id_update_script_finished_messager   )r   retain_lifecycle_msgsfragment_ids_this_runr/   s       r   clearzForwardMsgQueue.clearb   s    $ %DK@ !#9  ;;&C>>&) *5 		)  II1 #		 5 5 =#&99#8#8@U#U- 05JRV5VW&DK< !#=s   A0B c                >    | j                   }| j                          |S )zeClear the queue and return a list of the messages it contained
        before being cleared.
        )r   rA   )r   r   s     r   flushzForwardMsgQueue.flush   s     

r   c                ,    t        | j                        S r   r#   r   s    r   __len__zForwardMsgQueue.__len__   s    4;;r   )r   r   returnNone)rF   zdict[str, Any])rF   bool)r/   r   rF   rG   )FN)r?   rH   r@   zlist[str] | NonerF   rG   )rF   zlist[ForwardMsg])rF   int)__name__
__module____qualname____doc__r   __annotations__staticmethodr   r   r!   r%   r5   rA   rC   rE    r   r   r
   r
      s     @D<CA?A	A A?
% D ',263##3#  03# 
	3#j r   r
   c                t    | j                  d      sy| j                  j                  d      }|dk7  xr |dk7  S )zHTrue if the ForwardMsg is potentially composable with other ForwardMsgs.r-   Fr7   add_rowsarrow_add_rows)HasFieldr-   r<   )r/   
delta_types     r   r'   r'      s=    << 
 %%f-J#F
6F(FFr   c                p    | j                  d      }|dk(  ry|j                  d      }|dk(  r|S |dk(  r|S y)aJ  Combines new_delta onto old_delta if possible.

    If the combination takes place, the function returns a new Delta that
    should replace old_delta in the queue.

    If the new_delta is incompatible with old_delta, the function returns None.
    In this case, the new_delta should just be appended to the queue as normal.
    r7   	add_blockNnew_element)r<   )	old_delta	new_deltaold_delta_typenew_delta_types       r   r,   r,      sP     ))&1N$ ))&1N&$r   c                    | j                  d      dk(  rJ|du s'| j                  t        j                  j                  k7  rt        j                  j
                  | _        | S )a-  
    When we are here, the message queue is cleared from non-lifecycle messages
    before they were flushed to the browser.

    If there were no non-lifecycle messages in the queue, changing the type here
    should not matter for the frontend anyways, so we optimistically change the
    `script_finished` message to `FINISHED_EARLY_FOR_RERUN`. This indicates to
    the frontend that the previous run was interrupted by a new script start.
    Otherwise, a `FINISHED_SUCCESSFULLY` message might trigger a reset of widget
    states on the frontend.
    r7   r:   F)r<   r:   r   ScriptFinishedStatusFINISHED_SUCCESSFULLYFINISHED_EARLY_FOR_RERUN)r/   is_fragment_runs     r   r>   r>      sS     ~~f!22 	5 *"A"A"W"WW(==VVJr   N)r/   r   rF   rH   )rY   r   rZ   r   rF   zDelta | None)r/   r   ra   rH   rF   r   )
__future__r   typingr   r   r   streamlit.proto.ForwardMsg_pb2r   streamlit.proto.Delta_pb2r   r
   r'   r,   r>   rP   r   r   <module>rf      sO    # / / 5/G  G T
G!H	&*r   