-
Notifications
You must be signed in to change notification settings - Fork 6
Handle Yjs awareness on the widget comm #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0c4c141
a295d55
065df6f
7964b05
1cac496
2d86227
61782e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,12 +9,14 @@ | |||||||||||||||
| from anyio.abc import TaskGroup | ||||||||||||||||
| from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream | ||||||||||||||||
| from pycrdt import ( | ||||||||||||||||
| Awareness, | ||||||||||||||||
| YMessageType, | ||||||||||||||||
| YSyncMessageType, | ||||||||||||||||
| TransactionEvent, | ||||||||||||||||
| create_sync_message, | ||||||||||||||||
| create_update_message, | ||||||||||||||||
| handle_sync_message, | ||||||||||||||||
| read_message, | ||||||||||||||||
| ) | ||||||||||||||||
| from ypywidgets import Widget | ||||||||||||||||
| from ypywidgets.comm import CommWidget | ||||||||||||||||
|
|
@@ -112,6 +114,7 @@ def __init__( | |||||||||||||||
| self.remote_widget: Widget | None = None | ||||||||||||||||
| self.local_widget_created = Event() | ||||||||||||||||
| self.remote_widget_created = Event() | ||||||||||||||||
| self._remote_awareness: Awareness | None = None | ||||||||||||||||
| context.add_task(self.receive) | ||||||||||||||||
|
|
||||||||||||||||
| def send(self, event: TransactionEvent) -> None: | ||||||||||||||||
|
|
@@ -150,6 +153,13 @@ async def receive(self) -> None: | |||||||||||||||
| if message[1] == YSyncMessageType.SYNC_STEP2: | ||||||||||||||||
| self.sub = self.remote_widget.ydoc.observe(self.send) | ||||||||||||||||
| self.remote_widget_created.set() | ||||||||||||||||
| case YMessageType.AWARENESS: # pragma: nocover | ||||||||||||||||
| if self._remote_awareness is None: | ||||||||||||||||
| self._remote_awareness = Awareness( | ||||||||||||||||
| self.remote_widget.ydoc # pragma: no | ||||||||||||||||
| ) | ||||||||||||||||
| payload = read_message(bytes(message[1:])) | ||||||||||||||||
| self._remote_awareness.apply_awareness_update(payload, None) | ||||||||||||||||
|
Comment on lines
+156
to
+162
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above.
Suggested change
|
||||||||||||||||
|
|
||||||||||||||||
| async def get_local_widget(self, timeout: float = 0.2) -> CommWidget: | ||||||||||||||||
| with fail_after(timeout): | ||||||||||||||||
|
|
||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from __future__ import annotations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import pytest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pycrdt import Awareness, Doc, YMessageType, create_awareness_message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytestmark = pytest.mark.anyio | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def test_comm_provider_applies_awareness_frame(synced_widgets, context): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async with context: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local_widget = await synced_widgets.get_local_widget() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remote_awareness = Awareness(Doc()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remote_awareness.set_local_state({"role": "remote"}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| payload = remote_awareness.encode_awareness_update([remote_awareness.client_id]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| frame = create_awareness_message(payload) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert frame[0] == YMessageType.AWARENESS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local_widget._comm_provider._receive({"buffers": [frame]}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remote_state = local_widget.awareness.states.get(remote_awareness.client_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert remote_state is not None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert remote_state.get("role") == "remote" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def test_comm_widget_exposes_provider_awareness(synced_widgets, context): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async with context: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| widget = await synced_widgets.get_local_widget() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert widget.awareness is widget._comm_provider.awareness | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+29
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You just need a
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def test_comm_widget_awareness_observe_and_unobserve(synced_widgets, context): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async with context: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| widget = await synced_widgets.get_local_widget() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| events: list[str] = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sub_id = widget.awareness.observe(lambda topic, _: events.append(topic)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| widget.awareness.set_local_state({"ping": 1}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert events | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| widget.awareness.unobserve(sub_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| events.clear() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| widget.awareness.set_local_state({"ping": 2}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert events == [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+32
to
+45
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're not supporting the kernel setting the awareness, no need to test it?