11from __future__ import annotations
2+ from typing import Any , Callable
23
34import comm
45from pycrdt import (
6+ Awareness ,
57 Doc ,
68 Text ,
79 TransactionEvent ,
1012 create_sync_message ,
1113 create_update_message ,
1214 handle_sync_message ,
15+ read_message ,
1316)
1417
1518from .widget import Widget
@@ -48,18 +51,27 @@ def __init__(
4851 ) -> None :
4952 self ._ydoc = ydoc
5053 self ._comm = comm
54+ self ._awareness = Awareness (ydoc )
5155 msg = create_sync_message (ydoc )
5256 self ._comm .send (buffers = [msg ])
5357 self ._comm .on_msg (self ._receive )
5458
59+ @property
60+ def awareness (self ) -> Awareness :
61+ return self ._awareness
62+
5563 def _receive (self , msg ):
5664 message = bytes (msg ["buffers" ][0 ])
57- if message [0 ] == YMessageType .SYNC :
65+ mtype = message [0 ]
66+ if mtype == YMessageType .SYNC :
5867 reply = handle_sync_message (message [1 :], self ._ydoc )
5968 if reply is not None :
6069 self ._comm .send (buffers = [reply ])
6170 if message [1 ] == YSyncMessageType .SYNC_STEP2 :
6271 self ._ydoc .observe (self ._send )
72+ elif mtype == YMessageType .AWARENESS :
73+ payload = read_message (message [1 :])
74+ self ._awareness .apply_awareness_update (payload , None )
6375
6476 def _send (self , event : TransactionEvent ):
6577 update = event .update
@@ -69,12 +81,12 @@ def _send(self, event: TransactionEvent):
6981
7082class CommWidget (Widget ):
7183 def __init__ (
72- self ,
73- ydoc : Doc | None = None ,
74- comm_data : dict | None = None ,
75- comm_metadata : dict | None = None ,
76- comm_id : str | None = None ,
77- ):
84+ self ,
85+ ydoc : Doc | None = None ,
86+ comm_data : dict | None = None ,
87+ comm_metadata : dict | None = None ,
88+ comm_id : str | None = None ,
89+ ):
7890 super ().__init__ (ydoc )
7991 model_name = self .__class__ .__name__
8092 _model_name = self .ydoc ["_model_name" ] = Text ()
@@ -85,7 +97,21 @@ def __init__(
8597 create_ydoc = not ydoc ,
8698 )
8799 self ._comm = create_widget_comm (comm_data , comm_metadata , comm_id )
88- CommProvider (self .ydoc , self ._comm )
100+ self ._comm_provider = CommProvider (self .ydoc , self ._comm )
101+
102+ @property
103+ def awareness (self ) -> Awareness :
104+ return self ._comm_provider .awareness
105+
106+ def on_awareness_change (
107+ self ,
108+ callback : Callable [[str , tuple [dict [str , Any ], Any ]], None ],
109+ ) -> str :
110+ """Subscribe to pycrdt Awareness updates; returns subscription id for unobserve."""
111+ return self .awareness .observe (callback )
112+
113+ def unobserve_awareness (self , subscription_id : str ) -> None :
114+ self .awareness .unobserve (subscription_id )
89115
90116 def _repr_mimebundle_ (self , * args , ** kwargs ): # pragma: nocover
91117 plaintext = repr (self )
0 commit comments