-
Notifications
You must be signed in to change notification settings - Fork 289
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
Add component diffing on event responses. #167
Conversation
Here's an example for a TS unit test:
mesop/mesop/web/src/dev_tools/BUILD Lines 28 to 43 in a795a41
|
Re: running w/ tests on and off - I think the environmental variable idea would work, you can also look at https://playwright.dev/docs/test-parameterize#introduction for some other ideas of how to parameterize test. Also, I'd recommend adding some e2e tests with reasonably complex trees, multiple levels in the tree, different types of components & mutations (e.g. adding/deleting children) because most of our e2e tests are quite simple (usually 1 component with minimal hierarchy and mutations). |
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.
Left some comments. Overall, this is looking quite promising - great work!
componentDiff !== undefined && | ||
this.rootComponent !== undefined | ||
) { | ||
// Angular does not update the UI if we apply the diff on the root |
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.
Let's try to avoid copying the proto, which can be quite expensive.
I think we can solve this by modifying Shell's onRender function (
mesop/mesop/web/src/shell/shell.ts
Line 67 in a795a41
onRender: (rootComponent, componentConfigs) => { |
this.changeDetectorRef.detectChanges();
We do this for markdown:
this.changeDetectorRef.detectChanges(); |
angular docs: https://angular.io/api/core/ChangeDetectorRef#detectchanges
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.
I tested this out. But I was getting weird behavior in the chat widget case. The streaming text wasn't showing updates as the text was being generated. So I kept the current copy behavior for now. I'll try again later.
Thanks for the pointer to the typescript tests. That worked for me. Haven't got a chance to look into the Playwright flag stuff yet. Also haven't added more complex e2e examples, but agreed that it would be good to have them. Will get to those later this week. |
@@ -62,9 +83,24 @@ def node_slot_children_count(self) -> int | None: | |||
def set_current_node(self, node: pb.Component) -> None: | |||
self._current_node = node | |||
|
|||
def set_previous_node_from_current_node(self) -> None: |
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.
I don't think this method is being called anywhere? I tried running your PR locally, but I don't actually see any component diffs happening, I think because this method isn't actually being used.
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.
Doh, good catch. Looks like a regression when I added the reset_nodes method. It was supposed to call set_previous_node_from_current_node there.
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.
I patched your CL but I still don't see any component diffs. If you check the Chrome DevTools console logs, the protos received from the server are logged there. I don't see any component diffs in the proto.
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.
Ok, I think I got it working now 🤞🏾. Turns I didn't catch it because I was manually testing on the chat app which does the streaming response. But with the non-streaming response events it was not returning a diff. So basically the diff was not working on the first loop since previous node was not being set.
So that's the one thing I haven't figured out yet. I had to add back the original trace_mode loop code rather than existing early. However, I'm not sure why that works. I'm probably missing something pretty subtle.
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.
SGTM, we can debug this some more later.
d726a39
to
c92fa7d
Compare
Added an e2e test to better test more complex diffing scenarios. |
This change is gated by a flag called `enable_component_tree_diffs`. When enabled, the full component tree will not be returned in event responses. Instead only the changed compnent fields will be returned to the frontend. The frontend will then apply the diff to update its copy of the component tree.
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.
LGTM - great job!
This change is gated by a flag called
enable_component_tree_diffs
. When enabled, the full component tree will not be returned in event responses. Instead only the changed component fields will be returned to the frontend. The frontend will then apply the diff to update its copy of the component tree.A few notes:
Ref #62, #84