o
    .j                     @  s   d dl mZ d dlZd dlmZ d dlmZmZ zddlm	Z	 W n e
y/   ddlmZ	 Y nw zd dlmZ W n e
yC   dZY nw ejrMdd	lmZ G d
d de	ZdS )    )annotationsN)Promise)create_proxyrun_sync   )WebSocketExtensionFromHTTP)RawExtensionFromHTTP)	WebSocket)HTTPResponsec                   @  sZ   e Zd ZdZdddZdd
dZedddZdddZdddZ	d ddZ
d ddZdS )!PyodideWebSocketExtensionan  WebSocket extension for Pyodide using the browser's native WebSocket API.

    Synchronous via JSPI (run_sync). Uses JS Promises for signaling instead of
    asyncio primitives, because run_sync bypasses the asyncio event loop.
    Messages from JS callbacks are buffered in a list and delivered via
    next_payload() which blocks via run_sync on a JS Promise.
    urlstrreturnNonec                   s  t d u rtdd_g _d _d _g _t |_dj_	d d d d fd
d}t
|}t|}j| d fdd}d fdd}dfdd}dfdd}d|fd|fd|fd|ffD ]\}	}
t
|
}j| tj|	| qft| d S )NzoWebSocket is not available in this JavaScript runtime. Browser environment required (not supported in Node.js).Farraybufferresolverejectr   
typing.Anyr   r   r   c                   s   |  d< | d< d S Nr   r    r   _open_stater   T/home/thesage/.local/lib/python3.10/site-packages/niquests/extensions/pyodide/_ws.py_open_executor7   s   z:PyodideWebSocketExtension.__init__.<locals>._open_executoreventc                   s.    d }|d urd  d< d  d< |  d S d S r   r   r   rr   r   r   _onopenA   s   
z3PyodideWebSocketExtension.__init__.<locals>._onopenc                   s0    d }|d urd  d< d  d< |d d S d S )Nr   r   zWebSocket connection failedr   r   r   r   r   _onerrorH   s   z4PyodideWebSocketExtension.__init__.<locals>._onerrorc                   sX   | j }t|tr|}nt| } jd ur$| _ j}d  _|  d S  j| d S N)	data
isinstancer   bytesto_py_waiting_resolve	_last_msg_pendingappend)r   r!   msgr   selfr   r   
_onmessageO   s   


z6PyodideWebSocketExtension.__init__.<locals>._onmessagec                   s6    j d urd  _ j }d  _ |  d S  jd  d S r    )r%   r&   r'   r(   r   r*   r   r   _onclose_   s   

z4PyodideWebSocketExtension.__init__.<locals>._oncloseonopenonerror	onmessageoncloser   r   r   r   r   r   )r   r   r   r   )JSWebSocketOSError_closedr'   r%   r&   _proxiesnew_ws
binaryTyper   r   r(   setattrr   )r+   r   r   
exec_proxyopen_promiser   r   r,   r-   namefnproxyr   )r   r+   r   __init__   s>   
z"PyodideWebSocketExtension.__init__responser
   c                 C  s   t r    )NotImplementedError)r+   rA   r   r   r   startv   s   zPyodideWebSocketExtension.startboolc                 C  s   | j S r    )r5   r*   r   r   r   closedy   s   z PyodideWebSocketExtension.closedstr | bytes | Nonec                   sz    j rtd jr jd}|du rd _ |S d fd
d}t|}t|}t| |   j	}|du r;d _ |S )zpBlock (via JSPI) until the next message arrives.
        Returns None when the remote end closes the connection.!The WebSocket extension is closedr   NTr   r   r   r   r   c                   s
   |  _ d S r    )r%   r   r*   r   r   	_executor   s   
z9PyodideWebSocketExtension.next_payload.<locals>._executorr2   )
r5   r4   r'   popr   r   r7   r   destroyr&   )r+   r)   rH   r;   promiser   r*   r   next_payload}   s    
z&PyodideWebSocketExtension.next_payloadbufstr | bytesc                 C  sN   | j rtdt|ttfrddlm} | j|	| dS | j| dS )z"Send a message over the WebSocket.rG   r   )
Uint8ArrayN)
r5   r4   r"   r#   	bytearrayjsrO   r8   sendr7   )r+   rM   rO   r   r   r   send_payload   s   z&PyodideWebSocketExtension.send_payloadc                 C  s   dS )u@   No-op — browser WebSocket handles ping/pong at protocol level.Nr   r*   r   r   r   ping   s   zPyodideWebSocketExtension.pingc              	   C  sj   | j rdS d| _ z| j  W n	 ty   Y nw | jD ]}z|  W q ty-   Y qw | j  dS )z)Close the WebSocket and clean up proxies.NT)r5   r8   close	Exceptionr6   rJ   clear)r+   r?   r   r   r   rU      s   
zPyodideWebSocketExtension.closeN)r   r   r   r   )rA   r
   r   r   )r   rD   )r   rF   )rM   rN   r   r   )r   r   )__name__
__module____qualname____doc__r@   rC   propertyrE   rL   rS   rT   rU   r   r   r   r   r      s    

W


r   )
__future__r   typingrQ   r   pyodide.ffir   r   )packages.urllib3.contrib.webextensions.wsr   ImportError*packages.urllib3.contrib.webextensions.rawr   r	   r3   TYPE_CHECKINGpackages.urllib3r
   r   r   r   r   r   <module>   s"    