-
Notifications
You must be signed in to change notification settings - Fork 4
Add observe and observe_deep functions to Array, Map, Text, XmlElemen… #222
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?
Conversation
|
Warning Rate limit exceeded@satoren has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 6 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (17)
WalkthroughExtracts worker-routing logic from the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 2
🧹 Nitpick comments (3)
lib/doc.ex (1)
78-87: Consider callinghandle_on_update_handler()in the rescue block.The rescue block returns the error tuple without processing any pending callback messages. If callbacks were queued before the error occurred, they will be lost. Consider adding
handle_on_update_handler()before returning the error tuple to ensure callbacks are processed even when errors occur.🔎 Proposed fix
wrapped_fun = fn -> try do result = fun.() handle_on_update_handler() result rescue e -> + handle_on_update_handler() {Yex.Doc, :reraise, e, __STACKTRACE__} end endlib/shared_type/map.ex (2)
328-337: Add documentation for the public API.The
observe/2function is missing a@docannotation. Public APIs should include documentation explaining their purpose, parameters, and return values.🔎 Suggested documentation
+ @doc """ + Observes changes to the map by registering a callback handler. + The handler will be invoked whenever the map is modified within a transaction. + + ## Parameters + * `map` - The map to observe + * `handler` - A function that receives updates (Yex.MapEvent.t()) and origin + + ## Returns + A reference that can be used to unobserve later + + ## Examples + iex> doc = Yex.Doc.new() + iex> map = Yex.Doc.get_map(doc, "map") + iex> ref = Yex.Map.observe(map, fn event, origin -> + ...> IO.inspect({event, origin}) + ...> end) + """ @spec observe( t, handler :: (update :: Yex.MapEvent.t(), origin :: term() -> nil) ) :: reference() def observe(%__MODULE__{doc: doc} = map, handler) do Yex.SharedType.observe(map, metadata: {Yex.ObserveCallbackHandler, handler}, notify_pid: doc.worker_pid ) end
339-348: Add documentation for the public API.The
observe_deep/2function is missing a@docannotation. Public APIs should include documentation explaining their purpose, parameters, and how they differ from regularobserve/2.🔎 Suggested documentation
+ @doc """ + Observes deep changes to the map and nested structures by registering a callback handler. + Unlike observe/2, this also triggers for changes in nested shared types. + + ## Parameters + * `map` - The map to observe + * `handler` - A function that receives a list of updates and origin + + ## Returns + A reference that can be used to unobserve later + + ## Examples + iex> doc = Yex.Doc.new() + iex> map = Yex.Doc.get_map(doc, "map") + iex> ref = Yex.Map.observe_deep(map, fn updates, origin -> + ...> IO.inspect({updates, origin}) + ...> end) + """ @spec observe_deep( t, handler :: (update :: list(Yex.event_type()), origin :: term() -> nil) ) :: reference() def observe_deep(%__MODULE__{doc: doc} = map, handler) do Yex.SharedType.observe_deep(map, metadata: {Yex.ObserveCallbackHandler, handler}, notify_pid: doc.worker_pid ) end
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
lib/doc.exlib/shared_type/array.exlib/shared_type/event.exlib/shared_type/map.exlib/shared_type/shared_type.exlib/shared_type/text.exlib/shared_type/xml_element.exlib/shared_type/xml_fragment.exlib/shared_type/xml_text.exlib/y_ex.extest/doc_test.exstest/shared_type/array_test.exstest/shared_type/map_test.exstest/shared_type/text_test.exstest/shared_type/xml_element_test.exstest/shared_type/xml_fragment_test.exstest/shared_type/xml_text_test.exs
🧰 Additional context used
🧬 Code graph analysis (7)
lib/shared_type/text.ex (13)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/map.ex (2)
observe(332-337)observe_deep(343-348)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)native/yex/src/event.rs (2)
observe(449-486)observe_deep(397-438)native/yex/src/sync.rs (4)
term(34-34)term(83-83)term(105-105)term(112-112)native/yex/src/map.rs (1)
reference(36-38)native/yex/src/array.rs (1)
reference(40-42)native/yex/src/text.rs (1)
reference(45-47)native/yex/src/weak.rs (1)
reference(37-39)native/yex/src/shared_type.rs (1)
reference(56-56)native/yex/src/xml.rs (3)
reference(50-52)reference(87-89)reference(116-118)
test/doc_test.exs (1)
lib/doc.ex (5)
on_update(318-320)on_update_v1(324-337)transaction(212-233)on_update_v2(341-354)on_subdocs(302-315)
test/shared_type/xml_text_test.exs (2)
lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)
test/shared_type/text_test.exs (4)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)
lib/shared_type/xml_text.ex (6)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/map.ex (2)
observe(332-337)observe_deep(343-348)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)native/yex/src/event.rs (2)
observe(449-486)observe_deep(397-438)
lib/shared_type/array.ex (7)
lib/shared_type/map.ex (2)
observe(332-337)observe_deep(343-348)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)native/yex/src/event.rs (2)
observe(449-486)observe_deep(397-438)
lib/doc.ex (2)
native/yex/src/doc.rs (3)
doc_monitor_subdocs(455-487)doc_monitor_update_v1(297-328)doc_monitor_update_v2(330-360)lib/subscription.ex (1)
register(49-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint
🔇 Additional comments (22)
lib/doc.ex (2)
317-354: LGTM!The callback-based update APIs (
on_update,on_update_v1,on_update_v2) are well-structured and consistent with the existingmonitor_updatepattern. The delegation to NIF functions and subscription registration is correct.
356-372: LGTM!The recursive message handling in
handle_on_update_handler/0correctly drains callback messages from the mailbox. The non-blocking receive (timeout 0) ensures it terminates when no more messages are available, and the pattern matching covers the different callback handler types appropriately.lib/shared_type/shared_type.ex (2)
40-57: LGTM!The addition of
:notify_pidoption with a default toself()is well-designed. It maintains backward compatibility while enabling callers to route notifications to a different process (e.g., the document's worker process).
88-105: LGTM!The
:notify_pidoption is consistently implemented inobserve_deep/2, matching the pattern inobserve/2.lib/y_ex.ex (1)
18-23: LGTM!The
event_typeunion type provides a clean type definition for all supported event structures. This enhances type safety and documentation for the observe/observe_deep APIs.lib/shared_type/xml_element.ex (1)
354-374: LGTM!The
observe/2andobserve_deep/2implementations correctly delegate toYex.SharedTypewith appropriate metadata wrapping and worker process notification routing. The pattern is consistent with other shared type modules in the codebase.lib/shared_type/xml_text.ex (1)
142-162: LGTM!The
observe/2andobserve_deep/2functions are correctly implemented, following the same pattern used across all other shared type modules (Map, Text, Array, XmlElement, XmlFragment). The implementation properly routes notifications through the document's worker process.lib/shared_type/event.ex (1)
112-128: LGTM!The
Yex.WeakEventmodule follows the established pattern of other event types in this file. The struct and type definitions are correct and consistent.test/shared_type/xml_element_test.exs (2)
789-804: LGTM!The test correctly verifies that the observe handler is invoked with the expected event type and origin. The implementation follows the established testing pattern.
806-821: LGTM!The test correctly verifies deep observation callback behavior. The implementation is consistent with the observe test and follows established patterns.
test/shared_type/text_test.exs (2)
761-779: LGTM!The test correctly verifies the observe callback functionality for Text. Implementation is consistent with the pattern used across other shared types.
781-799: LGTM!The test correctly validates deep observation behavior for Text, following the established testing pattern.
test/shared_type/xml_text_test.exs (2)
355-375: LGTM!The test correctly validates the observe callback functionality for XmlText. The implementation is consistent with the testing patterns used across other shared types.
377-397: LGTM!The test correctly verifies deep observation callback behavior for XmlText, following the established testing pattern.
test/shared_type/map_test.exs (1)
248-280: LGTM! Well-structured tests for the new observe APIs.The tests properly verify handler invocation, event types, and origin propagation through the transaction mechanism.
test/shared_type/xml_fragment_test.exs (1)
483-515: LGTM! Consistent test coverage for XmlFragment observation.The tests follow the established pattern and properly validate callback invocation with XmlEvent payloads.
lib/shared_type/text.ex (1)
205-225: LGTM! Clean implementation following established patterns.The observe/observe_deep implementations correctly delegate to
Yex.SharedTypewith proper metadata wrapping and worker PID routing, consistent with the patterns used in Map, Array, and XML shared types.test/shared_type/array_test.exs (1)
520-558: LGTM! Comprehensive test coverage for Array observation with handlers.The tests properly validate both
Array.observeandArray.observe_deepwith callback handlers, complementing the existing SharedType-based observation tests.test/doc_test.exs (1)
549-660: LGTM! Excellent comprehensive test coverage for the new callback-based APIs.The test suite thoroughly validates:
- Basic callback invocation and update data structure
- Origin propagation through transactions
- Both v1 and v2 update variants
- Multiple concurrent callbacks
- Practical integration usage (lines 627-645 demonstrate cross-document sync)
- Subdocs callback registration
The integration test at lines 627-645 is particularly valuable as it demonstrates real-world usage of the update callback to synchronize documents.
lib/shared_type/array.ex (1)
391-400: LGTM! Consistent implementation with other shared types.The
observe/2function correctly follows the established pattern used in Map, Text, XmlElement, XmlText, and XmlFragment modules by delegating toYex.SharedType.observewith appropriate metadata and notify_pid.lib/shared_type/xml_fragment.ex (2)
283-292: LGTM! Consistent implementation with other shared types.The
observe/2function correctly follows the established pattern by delegating toYex.SharedType.observewith appropriate metadata and notify_pid from the document's worker process.
294-303: LGTM! Consistent implementation with other shared types.The
observe_deep/2function correctly follows the established pattern by delegating toYex.SharedType.observe_deepwith appropriate metadata and notify_pid. The typespec correctly matches the function name.
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.
Actionable comments posted: 1
♻️ Duplicate comments (2)
lib/shared_type/array.ex (1)
402-411: Fix typespec name mismatch.The
@specon line 402 declaresobservebut the function defined on line 406 isobserve_deep. This causes the typespec to be incorrectly associated with theobserve/2function above.🔎 Proposed fix
- @spec observe( + @spec observe_deep( Yex.Array.t(), handler :: (update :: list(Yex.event_type()), origin :: term() -> nil) ) :: reference()lib/doc.ex (1)
302-315: Fix typo in module name.Line 305 references
Yex.Dox.CallbackHandlerwhich should beYex.ObserveCallbackHandlerto match the pattern inhandle_on_update_handler/0at line 366.🔎 Proposed fix
def on_subdocs(%__MODULE__{} = doc, handler) do result = run_in_worker_process(doc, - do: Yex.Nif.doc_monitor_subdocs(doc, self(), {Yex.Dox.CallbackHandler, handler}) + do: Yex.Nif.doc_monitor_subdocs(doc, self(), {Yex.ObserveCallbackHandler, handler}) )
🧹 Nitpick comments (2)
test/doc_test.exs (1)
647-660: Consider adding a test that actually triggers subdocs events.The current test only verifies callback registration via
refute_receive. While useful for ensuring registration doesn't crash, it doesn't validate the callback is actually invoked when subdocs events occur. Consider adding a follow-up test that creates/loads subdocuments to trigger the event.lib/doc.ex (1)
63-66: Clarify the typespec for the doc parameter.The
atom()type in the spec seems unnecessary since the function accessesdoc.worker_pid, which requires a map/struct. Consider using just the map type or theYex.Doc.t()type.🔎 Proposed fix
- @spec run_in_worker_process_fn( - atom() | %{:worker_pid => any(), optional(any()) => any()}, - any() - ) :: any() + @spec run_in_worker_process_fn( + %{:worker_pid => pid() | nil, optional(any()) => any()}, + (-> any()) + ) :: any()
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
lib/doc.exlib/shared_type/array.exlib/shared_type/event.exlib/shared_type/map.exlib/shared_type/shared_type.exlib/shared_type/text.exlib/shared_type/xml_element.exlib/shared_type/xml_fragment.exlib/shared_type/xml_text.exlib/y_ex.extest/doc_test.exstest/shared_type/array_test.exstest/shared_type/map_test.exstest/shared_type/text_test.exstest/shared_type/xml_element_test.exstest/shared_type/xml_fragment_test.exstest/shared_type/xml_text_test.exs
🚧 Files skipped from review as they are similar to previous changes (9)
- test/shared_type/xml_fragment_test.exs
- lib/shared_type/map.ex
- test/shared_type/map_test.exs
- lib/shared_type/xml_element.ex
- test/shared_type/array_test.exs
- lib/shared_type/event.ex
- lib/shared_type/shared_type.ex
- lib/shared_type/xml_fragment.ex
- lib/shared_type/text.ex
🧰 Additional context used
🧬 Code graph analysis (4)
test/shared_type/text_test.exs (2)
lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)
lib/doc.ex (2)
native/yex/src/doc.rs (3)
doc_monitor_subdocs(455-487)doc_monitor_update_v1(297-328)doc_monitor_update_v2(330-360)lib/subscription.ex (1)
register(49-53)
test/shared_type/xml_text_test.exs (2)
lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)
test/shared_type/xml_element_test.exs (3)
lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)native/yex/src/event.rs (2)
observe(449-486)observe_deep(397-438)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint
🔇 Additional comments (15)
lib/shared_type/xml_text.ex (1)
142-162: LGTM! Observer APIs follow established patterns.The
observe/2andobserve_deep/2implementations correctly delegate toYex.SharedTypewith appropriate metadata and routing notifications throughdoc.worker_pid, consistent with similar implementations across other shared types.lib/y_ex.ex (1)
18-23: LGTM! Event type union correctly defined.The
event_typealias appropriately includes all event types (XmlTextEvent, TextEvent, MapEvent, ArrayEvent, WeakEvent), supporting the new observer APIs across shared types.test/shared_type/xml_text_test.exs (1)
355-397: LGTM! Tests adequately cover new observer APIs.Both tests correctly validate that:
- Handlers are invoked with the expected event types (XmlTextEvent for observe, list of events for observe_deep)
- Origin values are properly propagated through the callback chain
The test structure aligns with existing observer tests in the module.
test/shared_type/xml_element_test.exs (1)
789-821: LGTM! Observer handler tests are well-structured.The tests properly verify:
- Handler registration via
XmlElement.observe/observe_deep- Event delivery with correct event types (XmlEvent for observe, list for observe_deep)
- Origin propagation through the transaction
Consistent with the module's existing observer test patterns.
test/shared_type/text_test.exs (1)
761-799: LGTM! Handler-based observer tests are correctly implemented.Both tests validate the new
Text.observe/observe_deepAPIs by:
- Registering handlers that send messages to the test process
- Performing mutations within a transaction with a test origin
- Asserting proper callback invocation with TextEvent and origin
The pattern matches existing observer tests in the module.
test/doc_test.exs (5)
548-564: LGTM!The test properly verifies the
on_updatecallback registration and invocation, including assertions for both the callback being called and the update data being a non-empty binary.
566-583: LGTM!Good test coverage for
on_update_v1with transaction origin propagation. The test correctly verifies that the origin value is passed through to the callback.
585-599: LGTM!Basic coverage for
on_update_v2callback registration and invocation.
601-625: LGTM!Excellent test for multiple callback registration. It verifies that both callbacks are invoked independently and receive consistent update sizes, which is important for ensuring the callback mechanism doesn't corrupt data between handlers.
627-645: LGTM!This is a valuable integration test that verifies the update data can be used to synchronize another document, demonstrating the practical utility of the callback mechanism.
lib/shared_type/array.ex (1)
391-400: LGTM!The
observe/2implementation correctly delegates toYex.SharedType.observewith the handler wrapped in metadata and uses the document's worker_pid for notifications.lib/doc.ex (4)
55-61: LGTM!Good refactoring to extract the worker process routing logic into a dedicated function. The macro now cleanly delegates to
run_in_worker_process_fn/2.
67-104: LGTM!The worker process routing logic is well-structured with proper error handling and cross-process exception propagation via
reraise. The three cases (self, nil, other pid) are handled correctly.
317-337: LGTM!The
on_updateandon_update_v1functions are implemented correctly, registering the handler with the appropriate metadata wrapper and returning a subscription reference.
339-354: LGTM!The
on_update_v2implementation follows the same pattern ason_update_v1, correctly using the v2 variant of the NIF function.
4eaa6c5 to
fb7c308
Compare
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.
Actionable comments posted: 3
🧹 Nitpick comments (1)
lib/doc.ex (1)
317-321: Consider using a more precise return type spec.The
on_update/2,on_update_v1/2, andon_update_v2/2functions returnany()in their specs, but based on the implementation they return{:ok, reference()} | {:error, term()}. Consider aligning with the more specific return type used bymonitor_update/2for consistency and better documentation.🔎 Proposed fix
- @spec on_update(Yex.Doc.t(), handler :: (update :: binary(), origin :: term() -> nil)) :: any() + @spec on_update(Yex.Doc.t(), handler :: (update :: binary(), origin :: term() -> nil)) :: + {:ok, reference()} | {:error, term()} def on_update(%__MODULE__{} = doc, handler) do on_update_v1(doc, handler) end
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
lib/doc.exlib/shared_type/array.exlib/shared_type/event.exlib/shared_type/map.exlib/shared_type/shared_type.exlib/shared_type/text.exlib/shared_type/xml_element.exlib/shared_type/xml_fragment.exlib/shared_type/xml_text.exlib/y_ex.extest/doc_test.exstest/shared_type/array_test.exstest/shared_type/map_test.exstest/shared_type/text_test.exstest/shared_type/xml_element_test.exstest/shared_type/xml_fragment_test.exstest/shared_type/xml_text_test.exs
🚧 Files skipped from review as they are similar to previous changes (8)
- lib/shared_type/event.ex
- test/shared_type/xml_text_test.exs
- lib/shared_type/array.ex
- lib/shared_type/shared_type.ex
- lib/shared_type/text.ex
- test/shared_type/map_test.exs
- lib/shared_type/xml_element.ex
- test/shared_type/xml_element_test.exs
🧰 Additional context used
🧬 Code graph analysis (7)
test/shared_type/array_test.exs (2)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)
test/doc_test.exs (3)
lib/doc.ex (5)
new(123-125)on_update(318-320)on_update_v1(324-337)on_update_v2(341-354)on_subdocs(302-315)lib/y_ex.ex (1)
apply_update(103-105)lib/subscription.ex (1)
unsubscribe(66-78)
lib/shared_type/map.ex (6)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)
lib/shared_type/xml_fragment.ex (11)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/map.ex (2)
observe(332-337)observe_deep(343-348)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_text.ex (2)
observe(146-151)observe_deep(157-162)native/yex/src/event.rs (2)
observe(449-486)observe_deep(397-438)native/yex/src/array.rs (1)
reference(40-42)native/yex/src/map.rs (1)
reference(36-38)native/yex/src/text.rs (1)
reference(45-47)native/yex/src/shared_type.rs (1)
reference(56-56)native/yex/src/xml.rs (3)
reference(50-52)reference(87-89)reference(116-118)
test/shared_type/text_test.exs (2)
lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)
lib/shared_type/xml_text.ex (6)
lib/shared_type/array.ex (2)
observe(395-400)observe_deep(406-411)lib/shared_type/map.ex (2)
observe(332-337)observe_deep(343-348)lib/shared_type/shared_type.ex (2)
observe(40-57)observe_deep(88-105)lib/shared_type/text.ex (2)
observe(209-214)observe_deep(220-225)lib/shared_type/xml_element.ex (2)
observe(358-363)observe_deep(369-374)lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)
test/shared_type/xml_fragment_test.exs (1)
lib/shared_type/xml_fragment.ex (2)
observe(287-292)observe_deep(298-303)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint
🔇 Additional comments (17)
test/shared_type/array_test.exs (2)
520-538: LGTM!The test correctly verifies that
Array.observe/2invokes the handler with aYex.ArrayEventand the transaction origin.
540-558: LGTM!The test correctly verifies that
Array.observe_deep/2invokes the handler with a list of updates and the transaction origin.test/shared_type/xml_fragment_test.exs (2)
483-498: LGTM!The test correctly verifies that
XmlFragment.observe/2invokes the handler with aYex.XmlEventand the transaction origin.
500-515: LGTM!The test correctly verifies that
XmlFragment.observe_deep/2invokes the handler with a list of updates and the transaction origin.lib/shared_type/map.ex (2)
328-337: LGTM!The
observe/2implementation is consistent with other shared types and correctly wires the handler through the document's worker process.
339-348: LGTM!The
observe_deep/2implementation is consistent with other shared types and correctly wires the deep handler through the document's worker process.test/shared_type/text_test.exs (2)
761-779: LGTM!The test correctly verifies that
Text.observe/2invokes the handler with aYex.TextEventand the transaction origin.
781-799: LGTM!The test correctly verifies that
Text.observe_deep/2invokes the handler with a list of updates and the transaction origin.test/doc_test.exs (4)
4-4: LGTM!The alias addition for
Mapis appropriate for the new subdocs tests that useMap.set/3.
549-564: LGTM!The test correctly validates the
on_updatecallback registration, invocation, and data types.
566-645: LGTM!The
on_update_v1,on_update_v2, multiple callbacks, and sync tests are well-structured with correct callback signatures and comprehensive assertions.
662-692: LGTM!The subdocs event test correctly validates the callback receives
added,loaded, andremovedfields, and the error path test properly mocks the NIF with[:passthrough].lib/shared_type/xml_fragment.ex (1)
283-303: LGTM!The
observe/2andobserve_deep/2implementations are consistent with the pattern used across other shared types (Map,Text,Array,XmlElement,XmlText). The specs correctly referenceYex.XmlEvent.t()for shallow observation andlist(Yex.event_type())for deep observation.lib/shared_type/xml_text.ex (1)
142-162: LGTM!The
observe/2andobserve_deep/2implementations follow the same consistent pattern as other shared types, correctly usingYex.XmlTextEvent.t()for the observe callback and delegating toYex.SharedType.lib/doc.ex (3)
55-104: LGTM!The refactored
run_in_worker_processmacro and newrun_in_worker_process_fn/2cleanly encapsulate worker-routing logic with proper error propagation viareraise. The three cases (self, nil, other pid) are handled correctly with stacktrace preservation.
302-315: The code is correct as written.Yex.CallbackHandleris not a module but an atom constant used for message identification in thehandle_on_update_handler/0pattern matching (lines 358, 362, 366). This is intentional design—atoms tag different callback signatures. The distinction betweenYex.CallbackHandler(doc-level subscriptions) andYex.ObserveCallbackHandler(shared-type observers) is consistent throughout the codebase.
356-376: Verify NIF message formats match the receive patterns.The
handle_on_update_handler/0function handles multiple message formats. The patterns should match what the NIF sends:
- Line 358: 3-tuple
{_, arg1, {Yex.CallbackHandler, handler}}- Line 362: 4-tuple
{:subdocs, event, origin, {Yex.CallbackHandler, handler}}- Line 366: 4-tuple
{_, arg1, arg2, {Yex.CallbackHandler, handler}}- Line 370: 5-tuple
{_, _ref, event, origin, {Yex.ObserveCallbackHandler, handler}}These patterns need confirmation against the actual NIF message construction in
native/yex/src/doc.rsto ensure they match the tuples being sent.
Add callback function-based event handler registration functions to shared type modules: - Array, Map, Text, XmlElement, XmlFragment, and XmlText - observe: Subscribe to events with a callback function - observe_deep: Subscribe to deep events with a callback function This provides an alternative to the existing Subscription-based approach, allowing simpler event handling patterns for user applications.
…t, XmlFragment, and XmlText modules
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.