Parse-SDK-dotNET icon indicating copy to clipboard operation
Parse-SDK-dotNET copied to clipboard

feat: Add livequery support

Open theSlyest opened this issue 5 months ago • 2 comments

Added:

  • ParseLiveQuery class
  • ParseLiveQueryController class
  • ParseLiveQuerySubscription class
  • API ParseQuery.GetLive() for creating a ParseLiveQuery
  • LiveQueryServerConnectionData as a ServerConnectionData field to ParseClient to save live query server info.
  • APIs ConnectLiveQueryServerAsync(...) and DisconnectLiveQueryServerAsync(...) to ObjectServiceExtensions for connecting to and disconnecting respectively from the given parse live query server.
  • Some other smaller classes and interfaces...

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive real-time Live Query support with subscription management and event notifications for Parse object changes.
    • Added WebSocket client integration to enable persistent, event-driven communication with Live Query servers.
    • Enhanced service hubs and client classes to support live query connection data and controllers.
    • Added new methods for connecting to and disconnecting from Live Query servers.
    • Extended query classes to generate live queries from existing filters and manage live query subscriptions.
    • Included detailed event arguments for live query events and error handling.
    • Added support for separate Live Query server configuration in client initialization.
  • Bug Fixes

    • Minor whitespace cleanup in utility extension methods for improved code readability (no functional changes).

theSlyest avatar Jun 25 '25 12:06 theSlyest

🚀 Thanks for opening this pull request!

📝 Walkthrough

Walkthrough

Adds Parse Live Query support: new live-query connection data, WebSocket client and event args, message parser/builder, controller and subscription types, service-hub wiring and ParseClient overloads, query-to-live conversion and connect/disconnect helpers, plus unit tests.

Changes

Cohort / File(s) Change Summary
Connection data
Parse/Abstractions/Infrastructure/ILiveQueryServerConnectionData.cs, Parse/Infrastructure/LiveQueryServerConnectionData.cs
New ILiveQueryServerConnectionData interface and LiveQueryServerConnectionData struct with Timeout, MessageBufferSize, defaults and server/app keys/headers.
WebSocket client & events
Parse/Abstractions/Infrastructure/Execution/IWebSocketClient.cs, Parse/Infrastructure/Execution/MessageReceivedEventArgs.cs, Parse/Infrastructure/Execution/TextWebSocketClient.cs
Added IWebSocketClient (events + Open/Close/Send), MessageReceivedEventArgs, and TextWebSocketClient implementation (async open/close/send, listener loop, multi-frame handling, events, cancellation, disposal).
LiveQuery controller
Parse/Abstractions/Platform/LiveQueries/IParseLiveQueryController.cs, Parse/Platform/LiveQueries/ParseLiveQueryController.cs
New IParseLiveQueryController and concrete ParseLiveQueryController with states, Connect/Subscribe/Update/Unsubscribe/Close, per-request signaling, error eventing, lifecycle and disposal.
Message parser & builder
Parse/Abstractions/Platform/LiveQueries/IParseLiveQueryMessageParser.cs, Parse/Platform/LiveQueries/ParseLiveQueryMessageParser.cs, Parse/Abstractions/Platform/LiveQueries/IParseLiveQueryMessageBuilder.cs, Parse/Platform/LiveQueries/ParseLiveQueryMessageBuilder.cs
Added parser and builder interfaces and implementations to parse incoming messages and build connect/subscribe/update/unsubscribe payloads (includes LiveQueryError struct and session token injection).
Subscriptions & events
Parse/Abstractions/Platform/LiveQueries/IParseLiveQuerySubscription.cs, Parse/Platform/LiveQueries/ParseLiveQuerySubscription.cs, Parse/Platform/LiveQueries/ParseLiveQueryEventArgs.cs, Parse/Platform/LiveQueries/ParseLiveQueryDualEventArgs.cs, Parse/Platform/LiveQueries/ParseLiveQueryErrorEventArgs.cs
Added subscription contract and ParseLiveQuerySubscription<T>, event-arg types (single/dual-state and error), events, lifecycle methods and internal invokers.
LiveQuery API & query integration
Parse/Platform/LiveQueries/ParseLiveQuery.cs, Parse/Platform/Queries/ParseQuery.cs
New ParseLiveQuery<T> (filters, selected/watched keys, Watch, BuildParameters, SubscribeAsync) and ParseQuery<T>.GetLive() conversion.
Service hub integration
Parse/Abstractions/Infrastructure/...
Parse/Abstractions/Infrastructure/IServiceHub.cs, .../IMutableServiceHub.cs, .../CustomServiceHub.cs, Parse/Infrastructure/ServiceHub.cs, Parse/Infrastructure/MutableServiceHub.cs, Parse/Infrastructure/LateInitializedMutableServiceHub.cs, Parse/Infrastructure/OrchestrationServiceHub.cs
Extended hub interfaces and implementations to expose LiveQueryServerConnectionData, IWebSocketClient, IParseLiveQueryMessageParser, IParseLiveQueryMessageBuilder, and IParseLiveQueryController; added mutable setters and lazy initialization/delegation.
ParseClient wiring
Parse/Platform/ParseClient.cs
New constructor overload accepting ILiveQueryServerConnectionData with validation, test-mode handling, and application of service-hub configurators to wire live-query config.
Utilities / helpers
Parse/Utilities/ObjectServiceExtensions.cs
Added ConnectLiveQueryServerAsync and DisconnectLiveQueryServerAsync IServiceHub extension methods; tiny whitespace cleanup.
Tests — LiveQuery and related
Parse.Tests/*LiveQuery*.cs, Parse.Tests/MessageReceivedEventArgsTests.cs, Parse.Tests/TextWebSocketClientTests.cs
Added comprehensive unit tests for message builder/parser, controller/subscription behaviors, event args, TextWebSocketClient, and related components.
Tests — other adjustments
Parse.Tests/EncoderTests.cs, Parse.Tests/DecoderTests.cs, Parse.Tests/ObjectCoderTests.cs, Parse.Tests/SessionTests.cs, Parse.Tests/RelationTests.cs, Parse.Tests/UserTests.cs, Parse.Tests/Parse.Tests.csproj
Test setup changes (constructors call Client.Publicize()), moved some tests into Parse.Tests namespace, removed redundant signup calls, adjusted mocks/bindings, and updated test package versions.

Sequence Diagram(s)

Live Query Subscription Flow

sequenceDiagram
    autonumber
    participant App
    participant ParseQuery
    participant ParseLiveQuery
    participant LiveQueryController
    participant WebSocketClient
    participant Server

    App->>ParseQuery: GetLive()
    ParseQuery->>ParseLiveQuery: create
    App->>ParseLiveQuery: SubscribeAsync()
    ParseLiveQuery->>LiveQueryController: SubscribeAsync(liveQuery)
    LiveQueryController->>WebSocketClient: OpenAsync(serverUri)
    WebSocketClient->>Server: Open WebSocket
    LiveQueryController->>WebSocketClient: SendAsync(subscribe)
    Server-->>WebSocketClient: events (create/update/...)
    WebSocketClient-->>LiveQueryController: MessageReceived
    LiveQueryController-->>ParseLiveQuerySubscription: OnCreate/OnUpdate/...
    ParseLiveQuerySubscription-->>App: Raise event

Live Query Connect / Disconnect

sequenceDiagram
    participant App
    participant IServiceHub
    participant LiveQueryController
    participant WebSocketClient

    App->>IServiceHub: ConnectLiveQueryServerAsync(onError)
    IServiceHub->>LiveQueryController: ConnectAsync()
    LiveQueryController->>WebSocketClient: OpenAsync(serverUri)

    App->>IServiceHub: DisconnectLiveQueryServerAsync()
    IServiceHub->>LiveQueryController: CloseAsync()
    LiveQueryController->>WebSocketClient: CloseAsync()

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.42% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: Add livequery support" is concise and accurately summarizes the primary change (adding Live Query support, controller, subscription types, and related APIs) so it reflects the main changeset and follows conventional commit-style prefixing. It is specific enough for a teammate scanning history to understand the PR purpose without listing files or extraneous detail.
✨ Finishing touches
  • [ ] 📝 Generate Docstrings
🧪 Generate unit tests
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Jun 25 '25 12:06 coderabbitai[bot]

Is this work in progress?

mtrezza avatar Jun 30 '25 15:06 mtrezza

@mtrezza Is there something else I should do?

theSlyest avatar Jul 07 '25 15:07 theSlyest

Nice work! Does the LQ feature work - are you using it in an app, or did you test it out practically? I've started the CI.

mtrezza avatar Jul 07 '25 18:07 mtrezza

Nice work! Does the LQ feature work - are you using it in an app, or did you test it out practically? I've started the CI.

It works, I tested it out. I implemented it because I want to use it in an app.

theSlyest avatar Jul 09 '25 14:07 theSlyest

@mtrezza You can start the .NET checks again. They should be ok now.

theSlyest avatar Jul 10 '25 09:07 theSlyest

Done!

mtrezza avatar Jul 10 '25 09:07 mtrezza

@mtrezza Please, start the checks again. The tests were working on macOS, I had to run them on a Windows pc to get the error. I managed to fix them.

theSlyest avatar Jul 10 '25 14:07 theSlyest

Hello…

theSlyest avatar Jul 12 '25 14:07 theSlyest

Can someone start the .NET checks again, please?

theSlyest avatar Jul 21 '25 22:07 theSlyest

Taking a look. It uses a different pattern than the one I'm bringing forth which using RX.NET but I'll see, Yours is foundational which is very nice - Thank you kindly

YBTopaz8 avatar Jul 26 '25 01:07 YBTopaz8

Codecov Report

:x: Patch coverage is 36.60969% with 445 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 45.89%. Comparing base (2e81163) to head (a608262). :warning: Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...e/Platform/LiveQueries/ParseLiveQueryController.cs 0.00% 293 Missing :warning:
...se/Infrastructure/Execution/TextWebSocketClient.cs 60.33% 37 Missing and 11 partials :warning:
Parse/Platform/ParseClient.cs 51.02% 9 Missing and 15 partials :warning:
...atform/LiveQueries/ParseLiveQueryMessageBuilder.cs 65.11% 1 Missing and 14 partials :warning:
...Platform/LiveQueries/ParseLiveQuerySubscription.cs 43.47% 2 Missing and 11 partials :warning:
Parse/Infrastructure/MutableServiceHub.cs 7.69% 12 Missing :warning:
...Infrastructure/LateInitializedMutableServiceHub.cs 0.00% 9 Missing :warning:
Parse/Utilities/ObjectServiceExtensions.cs 0.00% 7 Missing :warning:
...se/Abstractions/Infrastructure/CustomServiceHub.cs 0.00% 5 Missing :warning:
Parse/Infrastructure/OrchestrationServiceHub.cs 0.00% 4 Missing and 1 partial :warning:
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #411      +/-   ##
==========================================
- Coverage   48.20%   45.89%   -2.31%     
==========================================
  Files         106      117      +11     
  Lines        6199     6898     +699     
  Branches      950     1139     +189     
==========================================
+ Hits         2988     3166     +178     
- Misses       2907     3362     +455     
- Partials      304      370      +66     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Jul 26 '25 01:07 codecov[bot]

In your file Parse\Platform\LiveQueries\ParseLiveQueryController.cs Line 395, you used windowsKey , is it left over test string? I was hoping to see ClientKey or dotNetKey, unless I am missing a point?

Do let me know please!

here

 Dictionary<string, object> message = new Dictionary<string, object>
 {
     { "op", "connect" },
     { "applicationId", ParseClient.Instance.Services.LiveQueryServerConnectionData.ApplicationID },
     { "windowsKey", ParseClient.Instance.Services.LiveQueryServerConnectionData.Key }
 };

YBTopaz8 avatar Jul 26 '25 01:07 YBTopaz8

Also, I'll be keeping an eye on this PR, it looks really good but has no tests linked to Live Queries from what I see.

My own suite of tests are really based on My implementation that uses RX.net so I can't port them over to your PR - sadly :(

So we will have to make them / establish a way to do so when this review is done.

YBTopaz8 avatar Jul 26 '25 01:07 YBTopaz8

In your file Parse\Platform\LiveQueries\ParseLiveQueryController.cs Line 395, you used windowsKey , is it left over test string? I was hoping to see ClientKey or dotNetKey, unless I am missing a point?

Do let me know please!

here

 Dictionary<string, object> message = new Dictionary<string, object>
 {
     { "op", "connect" },
     { "applicationId", ParseClient.Instance.Services.LiveQueryServerConnectionData.ApplicationID },
     { "windowsKey", ParseClient.Instance.Services.LiveQueryServerConnectionData.Key }
 };

It's based on the LiveQuery guide, and confirmed by Parse Server source code (src/LiveQuery/RequestSchema.js).

theSlyest avatar Jul 26 '25 05:07 theSlyest

That works. Now I'm about to do a PR that will simplify decoding and some other QOL changes alongside more unit tests.

You might have to review some parts of your code since it will be a breaking change and some tests would be terrific !

YBTopaz8 avatar Jul 26 '25 05:07 YBTopaz8

Just to chime in, very nice work @theSlyest, @YBTopaz8 that's quite some effort!

mtrezza avatar Jul 26 '25 11:07 mtrezza

@theSlyest I'd say your PR is good to merge. I would have hoped to get the new changes done before yours so you update in advance but here we are.

I'd approve and merge this if I am asked.

Thanks again for this.

YBTopaz8 avatar Jul 26 '25 14:07 YBTopaz8

@YBTopaz8 Don't worry, we can wait for your changes before merging this PR

theSlyest avatar Jul 26 '25 21:07 theSlyest

@mtrezza this looks good. If merged, I'll pull here and rework on my intended changes as a natural progression 🙂 You may merge this, please.

Thanks a lot @theSlyest . This solution works plainly which is superb. Now Parse Devs for .NET will have 2 options for Live Queries. I think we are the first with this luxury!

YBTopaz8 avatar Sep 01 '25 09:09 YBTopaz8

LGTM, should this be merged now?

@mtrezza It's ok now, I wanted to correct some potential issues first. You can run the tests and then merge.

theSlyest avatar Sep 01 '25 12:09 theSlyest

@mtrezza Anytime, my dear.

theSlyest avatar Sep 04 '25 10:09 theSlyest

Started the CI; @YBTopaz8 what do you mean by "Now Parse Devs for .NET will have 2 options for Live Queries."?

mtrezza avatar Sep 05 '25 09:09 mtrezza

Should this PR be merged, then the official SDK will have LQ.

There is another Parse LQ SDK that has LiveQueries but uses ReactiveX instead.

Done by myself. So it's unofficial

YBTopaz8 avatar Sep 05 '25 09:09 YBTopaz8

@mtrezza please retry, or update the check to use dotnet build (official .NET SDK) instead of msbuild (mono).

theSlyest avatar Sep 08 '25 12:09 theSlyest

Retry started

mtrezza avatar Sep 08 '25 14:09 mtrezza

@mtrezza I have added and updated some tests, please try again.

theSlyest avatar Sep 08 '25 19:09 theSlyest

Running again...

mtrezza avatar Sep 09 '25 16:09 mtrezza

Started CI

mtrezza avatar Sep 19 '25 12:09 mtrezza