Skip to content

Conversation

@xsahil03x
Copy link
Member

@xsahil03x xsahil03x commented Dec 29, 2025

Summary by CodeRabbit

  • New Features

    • Unified state-update event stream for richer real-time updates and a connection-state observable (plus a test-only state event accessor).
  • Bug Fixes

    • More reliable, consistent real-time synchronization across feeds, activities, comments, polls, bookmarks, reactions, and members.
  • Refactor

    • Consolidated add/update into upsert semantics; poll answer–specific APIs removed; several repository methods now return enriched composite results.
  • Tests

    • Tests updated to await and verify emitted state-update events.

✏️ Tip: You can customize this high-level summary in your review settings.

* Introduce `StateUpdateEvent` as an internal sealed class to map WebSocket events to state-specific updates.
* Replace `WsEvent` with `StateUpdateEvent` in all state notifiers, emitters, and event handlers.
* Decouple real-time event handling from direct WebSocket models to improve maintainability and type safety.
* Unify multiple "added/updated" handlers into `upsert` methods (e.g., `onBookmarkUpserted`, `onReactionUpserted`, `onPollVoteUpserted`).
* Add `FidScope` for more granular feed identifier matching in event handling.
* Remove `pollAnswerCasted` and `pollAnswerRemoved` resolvers in favor of integrated poll vote events.
- Rename `StateNotifierExtensions` to `StateNotifierExtension` and update related imports.
- Standardize constructor parameters across various list and state classes (e.g., `BookmarkFolderList`, `PollVoteList`, `ActivityList`, `Feed`).
- Shift responsibility for state updates from direct repository calls to an event-driven model using `MutableSharedEmitter<StateUpdateEvent>`.
- Refactor `FeedsRepository`, `ActivitiesRepository`, and `CommentsRepository` methods to return more comprehensive data types (e.g., records including both activity and reaction/comment).
- Remove unused `FollowBatchUpdate` event and related handler logic.
- Improve `MemberListStateNotifier` to merge updated and added members instead of simple replacement.
- Update tests in `feed_test.dart` and `activity_test.dart` to include `pumpEventQueue()` to account for asynchronous event-driven state updates.
- Remove redundant state-updating methods in `FeedStateNotifier` and `ActivityStateNotifier`.
@xsahil03x xsahil03x requested a review from a team as a code owner December 29, 2025 15:02
@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

Replaces WsEvent-based realtime wiring with a sealed StateUpdateEvent model and a client-side mapper; introduces a private MutableSharedEmitter, rewires state/list components and handlers to consume it, consolidates many add/update handlers into upsert variants, and updates several repository return types and poll-related resolvers/tests.

Changes

Cohort / File(s) Summary
Client & WS mapping
packages/stream_feeds/lib/src/client/feeds_client_impl.dart
Added _stateUpdateEmitter and _wsEventToStateMapperSubscription; map WsEventStateUpdateEvent; manage lifecycle on connect/disconnect; removed legacy resolver wiring.
New event model & scope
packages/stream_feeds/lib/src/state/event/state_update_event.dart, packages/stream_feeds/lib/src/state/event/fid_scope.dart, packages/stream_feeds/lib/src/state.dart
Added sealed StateUpdateEvent hierarchy with fromWsEvent factory and FidScope; exported state_update_event from state barrel.
Client API surface
packages/stream_feeds/lib/src/feeds_client.dart
Added connectionState getter and @visibleForTesting SharedEmitter<StateUpdateEvent> get stateUpdateEvents.
Event handler infra
packages/stream_feeds/lib/src/state/event/state_event_handler.dart
Interface updated: handleEvent now accepts StateUpdateEvent.
Event handlers
packages/stream_feeds/lib/src/state/event/handler/*
All handlers migrated to StateUpdateEvent; dispatch on domain events (Activity*, Comment*, Bookmark*, Poll*, Feed*, Follow*, FeedMember*); payloads use domain models; many handlers consolidated to upsert semantics with optional enforceUnique.
State / List components
packages/stream_feeds/lib/src/state/*.dart (Feed, FeedList, FollowList, Activity, ActivityList, ActivityReactionList, BookmarkList, BookmarkFolderList, CommentList, CommentReplyList, ActivityCommentList, PollList, PollVoteList, MemberList, ModerationConfigList, etc.)
Constructors now accept MutableSharedEmitter<StateUpdateEvent> and store private _eventsEmitter; subscriptions use StateUpdateEvent; notifiers consolidate add/update into Upserted variants; ModerationConfigList removed emitter dependency; some ctor parameter order changes.
State notifier utils
packages/stream_feeds/lib/src/state/state_notifier_extension.dart
Renamed extension to StateNotifierExtension<T>.
Repositories
packages/stream_feeds/lib/src/repository/activities_repository.dart, comments_repository.dart, feeds_repository.dart
Updated return types: activity reaction add/delete now return composite (activity, reaction); deleteComment returns (activity, comment); unfollow now returns FollowData (was void).
Models & resolvers
packages/stream_feeds/lib/src/models/poll_data.dart, packages/stream_feeds/lib/src/resolvers/poll/*, packages/stream_feeds/lib/src/resolvers/resolvers.dart
Removed poll answer helper methods and deleted poll answer resolver files; removed their exports from resolvers barrel; related tests removed.
Tests & test utils
packages/stream_feeds/test/state/*, packages/stream_feeds/test/resolvers/poll/*, packages/stream_feeds_test/lib/src/testers/base_tester.dart, packages/stream_feeds/test/client/feeds_client_test.dart
Tests updated to await stateUpdateEvents for synchronization; poll-answer resolver tests removed; BaseTester gained dispose(); some tests now observe connectionState directly.
Pubspec / bootstrap
melos.yaml, packages/stream_feeds/pubspec.yaml
Bumped stream_core dependency to ^0.4.0.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant WS as WebSocket (WsEvent)
  participant Mapper as WsEvent→StateUpdateEvent Mapper
  participant Emitter as _stateUpdateEmitter (MutableSharedEmitter)
  participant Handlers as State Event Handlers / Notifiers
  participant Client as StreamFeedsClientImpl

  Note over WS,Mapper: Incoming raw websocket events
  WS->>Mapper: deliver WsEvent
  alt mapper produces domain event
    Mapper-->>Emitter: StateUpdateEvent.fromWsEvent(WsEvent)
    Emitter-->>Handlers: broadcast StateUpdateEvent
    Handlers->>Handlers: handleEvent(StateUpdateEvent) → notifier updates
  else unknown / ignored
    Mapper-->>Emitter: UnknownStateUpdateEvent / no-op
  end
  Client->>Emitter: expose stateUpdateEvents / manage lifecycle (connect/disconnect)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • renefloor
  • Brazol

"🐰 I hopped through sockets, mapping every cluck,
WsEvent to StateUpdateEvent—now state updates pluck.
Upserts embrace adds and edits in a single sweep,
Poll-answer crumbs gone, reactions snug and neat 🥕✨"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is completely empty. The template requires a description explaining the changes, their rationale, testing approach, and other critical information, but none was provided by the author. Add a comprehensive description explaining the StateUpdateEvent refactoring: why it was needed, how it changes the architecture, testing performed, and any migration notes for API consumers.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor(llc): refactor state management to use StateUpdateEvent' clearly and specifically describes the main architectural change in the changeset, which involves migrating from WsEvent-based state handling to a new StateUpdateEvent system across the entire codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@xsahil03x xsahil03x changed the title feat(llc): refactor state management to use StateUpdateEvent refactor(llc): refactor state management to use StateUpdateEvent Dec 29, 2025
@codecov
Copy link

codecov bot commented Dec 29, 2025

Codecov Report

❌ Patch coverage is 99.75369% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.53%. Comparing base (d11f6b3) to head (6716555).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
packages/stream_feeds/lib/src/state/feed.dart 97.97% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main      #79   +/-   ##
=======================================
  Coverage   86.53%   86.53%           
=======================================
  Files         121      121           
  Lines        4197     4175   -22     
=======================================
- Hits         3632     3613   -19     
+ Misses        565      562    -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/stream_feeds/lib/src/repository/feeds_repository.dart (1)

215-219: Update documentation to reflect new return type.

The doc comment still states "Returns a [Result] containing void or an error" but the method now returns Result<FollowData>.

🔎 Suggested documentation fix
 /// Removes a follow relationship between feeds.
 ///
 /// Unfollows the [target] feed from the [source] feed.
 ///
-/// Returns a [Result] containing void or an error.
+/// Returns a [Result] containing the removed [FollowData] or an error.
packages/stream_feeds/lib/src/repository/activities_repository.dart (1)

193-197: Update documentation to reflect composite return type.

The doc comment states the method returns FeedsReactionData but it now returns a record with both ActivityData and FeedsReactionData.

🔎 Suggested documentation fix
 /// Adds a reaction to an activity.
 ///
 /// Creates a new reaction on the activity with [activityId] using the provided [request] data.
 ///
-/// Returns a [Result] containing the [FeedsReactionData] or an error.
+/// Returns a [Result] containing a record with the updated [ActivityData] and
+/// created [FeedsReactionData] or an error.
packages/stream_feeds/lib/src/repository/comments_repository.dart (1)

127-133: Update documentation to reflect composite return type.

The doc comment states "Returns a [Result] containing void or an error" but the method now returns a record with both ActivityData and CommentData.

🔎 Suggested documentation fix
 /// Deletes a comment.
 ///
 /// Removes the comment with the specified [commentId] from the system.
 ///
 /// If [hardDelete] is true, the comment is permanently deleted; otherwise, it may be soft-deleted.
 ///
-/// Returns a [Result] containing void or an error.
+/// Returns a [Result] containing a record with the related [ActivityData] and
+/// deleted [CommentData] or an error.
🧹 Nitpick comments (13)
packages/stream_feeds/lib/src/state/event/handler/comment_reaction_list_event_handler.dart (1)

4-5: Comment reaction event scoping and filtering look correct

  • Each branch correctly gates on event.comment.id == query.commentId, so only the target comment’s reactions affect this list.
  • Applying matches(query.filter) only on upsert keeps delete handling simple and robust (extra delete events become safe no‑ops).

If you later touch this file again, you could consider a switch (event) with patterns instead of chained if checks to match the rest of the StateUpdateEvent‑based handlers, but that’s purely stylistic here.

Also applies to: 21-40

packages/stream_feeds/lib/src/state/event/handler/activity_event_handler.dart (1)

3-5: ActivityEventHandler’s StateUpdateEvent routing appears consistent and well‑scoped

  • Activity, reaction, bookmark, and poll events all perform appropriate id (and for hidden, user) checks before mutating state, which keeps updates local to the relevant activity instance.
  • Consolidating bookmark add/update into a single onBookmarkUpserted path and using enforceUnique on reaction upserts matches the new upsert‑centric design.
  • Explicit no‑op branches for comment events document that they’re handled elsewhere without risking accidental fall‑through.

If you revisit this handler later, a switch (event) with patterns could reduce the long if chain and better express the sealed StateUpdateEvent hierarchy, but it’s not required for correctness.

Also applies to: 24-107

packages/stream_feeds/lib/src/state/event/handler/follow_list_event_handler.dart (1)

7-10: Minor: Documentation mentions WebSocket but handler now processes StateUpdateEvent.

The doc comment references "WebSocket events" but the handler now processes StateUpdateEvent which abstracts over both WebSocket and API-generated events. Consider updating the documentation for accuracy.

🔎 Suggested documentation update
 /// Event handler for follow list real-time updates.
 ///
-/// Processes WebSocket events related to follow relationships
+/// Processes state update events related to follow relationships
 /// and updates the follow list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/bookmark_list_event_handler.dart (1)

7-10: Minor: Documentation references WebSocket but handler processes StateUpdateEvent.

Similar to the follow handler, the doc comment mentions "WebSocket events" but this handler now processes the abstracted StateUpdateEvent.

🔎 Suggested documentation update
 /// Event handler for bookmark list real-time updates.
 ///
-/// Processes WebSocket events related to bookmarks
+/// Processes state update events related to bookmarks
 /// and updates the bookmark list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/comment_reply_list_event_handler.dart (1)

6-10: Minor documentation inconsistency.

The doc comment on lines 7-9 still references "WebSocket events" but the handler now processes StateUpdateEvent domain events. Consider updating the documentation to reflect the new event architecture.

🔎 Suggested documentation update
 /// Event handler for comment reply list real-time updates.
 ///
-/// Processes WebSocket events related to comments and their replies
+/// Processes state update events related to comments and their replies
 /// and updates the comment reply list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/poll_vote_list_event_handler.dart (1)

7-10: Minor documentation inconsistency.

Similar to other handlers, the doc comment references "WebSocket events" but the handler now processes StateUpdateEvent domain events.

🔎 Suggested documentation update
 /// Event handler for poll vote list real-time updates.
 ///
-/// Processes WebSocket events related to poll votes on a specific poll
+/// Processes state update events related to poll votes on a specific poll
 /// and updates the poll vote list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart (1)

7-10: Minor documentation inconsistency.

The doc comment references "WebSocket events" but the handler now processes StateUpdateEvent domain events.

🔎 Suggested documentation update
 /// Event handler for bookmark folder list real-time updates.
 ///
-/// Processes WebSocket events related to bookmark folders
+/// Processes state update events related to bookmark folders
 /// and updates the bookmark folder list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/activity_reaction_list_event_handler.dart (1)

5-8: Minor documentation inconsistency.

The doc comment references "WebSocket events" but the handler now processes StateUpdateEvent domain events.

🔎 Suggested documentation update
 /// Event handler for activity reaction list real-time updates.
 ///
-/// Processes WebSocket events related to reactions on a specific activity
+/// Processes state update events related to reactions on a specific activity
 /// and updates the activity reaction list state accordingly.
packages/stream_feeds/lib/src/state/event/handler/feed_event_handler.dart (1)

29-212: Consider using a switch expression for cleaner event dispatch.

The extensive if-else chain works correctly but could benefit from Dart's exhaustive switch expression pattern matching on the sealed StateUpdateEvent hierarchy. This would provide compile-time exhaustiveness checking and align with the coding guidelines recommending pattern matching with switch expressions.

That said, the current implementation is functional and readable. This is a refactor opportunity rather than a requirement.

packages/stream_feeds/lib/src/state/event/handler/activity_list_event_handler.dart (1)

31-143: Consider using a switch expression for exhaustiveness checking.

The current if-chain pattern works but doesn't provide compile-time exhaustiveness guarantees. Since StateUpdateEvent is a sealed class hierarchy, using Dart's pattern matching with switch would catch unhandled event types at compile time.

Example refactor using switch expression
@override
Future<void> handleEvent(StateUpdateEvent event) async {
  switch (event) {
    case ActivityAdded(:final activity, :final scope):
      if (!activity.matches(query.filter)) return;
      state.onActivityUpdated(activity);
      final updated = await withUpdatedFeedCapabilities(activity);
      if (updated != null) state.onActivityUpdated(updated);
      
    case ActivityUpdated(:final activity, :final scope):
      if (!activity.matches(query.filter)) {
        return state.onActivityRemoved(activity.id);
      }
      state.onActivityUpdated(activity);
      final updated = await withUpdatedFeedCapabilities(activity);
      if (updated != null) state.onActivityUpdated(updated);
      
    case ActivityDeleted(:final activityId):
      state.onActivityRemoved(activityId);
      
    // ... other cases
    
    case _:
      // Explicitly ignore unhandled events
      break;
  }
}
packages/stream_feeds/lib/src/state/event/handler/comment_list_event_handler.dart (1)

7-9: Update documentation to reflect StateUpdateEvent architecture.

The comment mentions "WebSocket events" but the handler now processes StateUpdateEvent instances, which are domain events at the state layer rather than raw WebSocket events.

🔎 Suggested documentation fix
 /// Event handler for comment list real-time updates.
 ///
-/// Processes WebSocket events and updates the comment list state accordingly.
+/// Processes state update events and updates the comment list state accordingly.
 class CommentListEventHandler implements StateEventHandler {
packages/stream_feeds/lib/src/state/event/handler/activity_comment_list_event_handler.dart (1)

5-8: Update documentation to reflect StateUpdateEvent.

The comment references "WebSocket events" but should describe the state-layer events being processed.

🔎 Suggested documentation fix
 /// Event handler for activity comment list real-time updates.
 ///
-/// Processes WebSocket events related to comments on a specific activity
+/// Processes state update events related to comments on a specific activity
 /// and updates the activity comment list state accordingly.
 class ActivityCommentListEventHandler implements StateEventHandler {
packages/stream_feeds/lib/src/client/feeds_client_impl.dart (1)

245-248: Consider making _wsEventToStateMapperSubscription non-nullable.

The subscription is assigned during construction and should always be non-null during the client's lifecycle. Using late final instead of nullable would better express this invariant and avoid the null-check in disconnect().

🔎 Suggested refactor
-  late final _stateUpdateEmitter = MutableSharedEmitter<StateUpdateEvent>();
-  StreamSubscription<WsEvent>? _wsEventToStateMapperSubscription;
+  late final _stateUpdateEmitter = MutableSharedEmitter<StateUpdateEvent>();
+  late final StreamSubscription<WsEvent> _wsEventToStateMapperSubscription;

And in disconnect():

-    await _wsEventToStateMapperSubscription?.cancel();
+    await _wsEventToStateMapperSubscription.cancel();

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_feeds/lib/src/state/feed_state.dart (1)

227-284: Incomplete refactoring: event handlers still call renamed methods with old names.

The rename from onBookmarkAdded, onCommentAdded, etc., to their Upserted equivalents improves API clarity by reflecting insert-or-update semantics. However, the refactoring is incomplete—the following event handlers still call the old method names and must be updated:

  • packages/stream_feeds/lib/src/state/event/handler/activity_comment_list_event_handler.dart:33 calls onCommentAdded
  • packages/stream_feeds/lib/src/state/event/handler/comment_list_event_handler.dart:25 calls onCommentAdded
  • packages/stream_feeds/lib/src/state/event/handler/bookmark_list_event_handler.dart:34 calls onBookmarkAdded

Update all event handlers to call the new onBookmark**Upserted**, onComment**Upserted**, etc., methods.

🤖 Fix all issues with AI Agents
In @packages/stream_feeds/lib/src/client/feeds_client_impl.dart:
- Around line 245-248: StreamFeedsClientImpl is missing the concrete getter
required by StreamFeedsClient; implement Stream<StateUpdateEvent> get
stateUpdateEvents in StreamFeedsClientImpl to return the stream from the
existing _stateUpdateEmitter (e.g., _stateUpdateEmitter.stream) and ensure the
StreamFeedsClient interface declares the same signature Stream<StateUpdateEvent>
get stateUpdateEvents; so callers (tester.client.stateUpdateEvents) remain
type-safe.

In @packages/stream_feeds/lib/src/state.dart:
- Line 20: The public barrel export in state.dart is exposing types from
state_update_event.dart that are annotated @internal; remove the line "export
'state/event/state_update_event.dart';" from state.dart to keep those types
internal, then create a dedicated test-only helper file that re-exports
state_update_event.dart for tests (so StreamFeedsClient.stateUpdateEvents can
remain @visibleForTesting), or alternatively drop the @internal annotation if
these types truly belong in the public API — pick one approach and apply it
consistently.
🧹 Nitpick comments (2)
packages/stream_feeds/test/state/feed_test.dart (1)

2001-2056: Minor naming/comment cleanup in queryMoreFeedMembers test

The queryMoreFeedMembers test body talks about "comment" and stores the result in a comments variable, while the API/query clearly concerns members. Consider renaming for clarity:

  • Update the comment // Initial state - has comment to refer to members.
  • Rename comments to members in this test (and keep the type as-is).

This is purely cosmetic but will make the test intent clearer.

Proposed diff for the test body
@@
-        // Load initial members
+        // Load initial members
         await tester.feed.queryFeedMembers();
 
-        // Initial state - has comment
-        expect(tester.feedState.members, hasLength(1));
-        expect(tester.feedState.canLoadMoreMembers, isTrue);
+        // Initial state - has one member
+        expect(tester.feedState.members, hasLength(1));
+        expect(tester.feedState.canLoadMoreMembers, isTrue);
@@
         final result = await tester.feed.queryMoreFeedMembers();
 
         expect(result.isSuccess, isTrue);
-        final comments = result.getOrNull();
-        expect(comments, isNotNull);
-        expect(comments, hasLength(1));
+        final members = result.getOrNull();
+        expect(members, isNotNull);
+        expect(members, hasLength(1));
 
         // Verify state was updated
         expect(tester.feedState.members, hasLength(2));
         expect(tester.feedState.canLoadMoreMembers, isFalse);

Also applies to: 2057-2071

packages/stream_feeds/lib/src/client/feeds_client_impl.dart (1)

270-276: Emitter disposal semantics on disconnect may make the client single-use

Currently disconnect() cancels _wsEventToStateMapperSubscription and calls _stateUpdateEmitter.close(). That’s perfectly fine if disconnect is effectively the terminal “dispose” for the client; however, if you expect callers to reuse the same StreamFeedsClientImpl instance and call connect() again, closing the emitter will prevent any further stateUpdateEvents from being consumed.

If reuse after disconnect() is a supported scenario, consider either:

  • Not closing _stateUpdateEmitter here (let the client be GC’d instead), or
  • Converting _stateUpdateEmitter to a non‑late final and reinitializing it together with a new mapper subscription on reconnect.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 83ff5e2 and 08932a0.

📒 Files selected for processing (8)
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/feed_test.dart
🧰 Additional context used
📓 Path-based instructions (6)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/src/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Use // for internal/private code documentation

Files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/src/state/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/state/**/*.dart: State classes must use @freezed with const constructors
State class naming convention: Use *State suffix for state classes (e.g., FeedState, ActivityListState)

Files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/test/**/*.dart: Test through public APIs only, not internal StateNotifier implementations
Use HTTP interceptors instead of mocking repositories in tests
Mirror the lib/ structure in test/ directory organization

Files:

  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
{**/api/**/*.dart,**/*_api.dart,**/client/*.dart}

📄 CodeRabbit inference engine (.cursor/rules/stream-feeds-api.mdc)

{**/api/**/*.dart,**/*_api.dart,**/client/*.dart}: Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter
Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes
Use batch operations for bulk activity creation and updates to optimize API performance
Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Respect API rate limiting by implementing retry logic with retry-after headers and designing applications to handle rate limit responses gracefully
Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions
Use connection pooling and gzip compression for efficient HTTP connection management and reduced bandwidth when communicating with Stream Feeds API

Files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
🧠 Learnings (37)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Design WebSocket integration for real-time updates through structured event handling and pattern matching
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Consider WebSocket real-time updates and implications in SDK architecture
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : StateNotifier naming convention: Use `*StateNotifier` suffix for StateNotifier implementations (e.g., `FeedStateNotifier`)

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit generated files (`*.freezed.dart`, `*.g.dart`, `src/generated/`)

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State classes must use `freezed` with const constructors

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Plan for StateNotifier reactive patterns when implementing state management in Dart

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Compose complex states from simpler freezed components using copyWith for immutable updates

Applied to files:

  • packages/stream_feeds/lib/src/state.dart
  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Follow Freezed 3.0 mixed mode syntax with `override` annotations for fields

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Use `freezed` for all data classes in the Stream Feeds SDK

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use immutable freezed models for all data classes with required id fields

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Use freezed for all data classes with required id fields and const constructors

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Place custom data fields last in constructors and class definitions

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.freezed.dart
  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds/test/state/feed_test.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds/test/state/feed_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use connection pooling and gzip compression for efficient HTTP connection management and reduced bandwidth when communicating with Stream Feeds API

Applied to files:

  • packages/stream_feeds/lib/src/feeds_client.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/ws/events/**/*.dart : Real-time event handlers must use `freezed` for type-safe event handling in WebSocket layer

Applied to files:

  • packages/stream_feeds/lib/src/feeds_client.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use batch operations for bulk activity creation and updates to optimize API performance

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : All repository methods must return `Result<T>` types for explicit error handling

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use early return patterns for validation and errors in repository methods

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Never throw exceptions in repositories - always return Result types

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Implement reactive state management with StateNotifier-based state management and automatic notifications

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/feed_state.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Implement reactive state management with automatic change notifications using StateNotifier

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/lib/src/state/feed_state.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
🪛 GitHub Actions: legacy_version_analyze
packages/stream_feeds/lib/src/client/feeds_client_impl.dart

[error] 60-60: Missing concrete implementation of 'getter StreamFeedsClient.stateUpdateEvents'. Try implementing the missing method, or make the class abstract. - non_abstract_class_inherits_abstract_member

⏰ 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). (2)
  • GitHub Check: build
  • GitHub Check: stream_feeds
🔇 Additional comments (13)
packages/stream_feeds/lib/src/state/feed_state.dart (5)

48-57: LGTM! Clean state synchronization pattern.

The member list synchronization properly propagates changes from the memberList state notifier and is correctly disposed of in the dispose method.


59-81: LGTM! Well-documented synchronization approach.

The comment clearly explains why members are synchronized through the memberList state notifier rather than directly assigned, avoiding potential state conflicts.


445-522: LGTM! Clean pagination support.

The new membersPagination field and canLoadMoreMembers getter follow the established pattern used for activities pagination. The addition of canLoadMoreActivities provides good API symmetry.


36-43: Constructor parameter reordering is a breaking API change.

The initialState parameter has been moved after memberList. This is a breaking change that will require updates in all call sites. Verify that all instantiation sites of FeedStateNotifier throughout the codebase have been updated to match the new parameter order.


140-142: All call sites have been correctly updated for the signature change.

The onActivityRemoved method signature change to accept String activityId is properly implemented across all five call sites in the event handlers. Every invocation correctly passes a String identifier (event.activity.id or event.activityId) rather than an ActivityData object.

packages/stream_feeds/lib/src/state/feed_state.freezed.dart (1)

1-194: Generated code - no review required.

This is auto-generated freezed code that correctly reflects the membersPagination field addition to FeedState.

packages/stream_feeds/lib/src/state/event/state_update_event.dart (2)

93-127: LGTM! Correct enforceUnique semantics.

The factory method correctly sets enforceUnique: false for added reactions (allowing multiple reactions) and enforceUnique: true for updated reactions (replacing existing reactions of the same type).


330-857: LGTM! Well-structured event hierarchy.

The event classes are well-designed with:

  • Const constructors for efficiency
  • Clear documentation
  • Consistent structure
  • Appropriate use of sealed class hierarchy for exhaustive pattern matching
packages/stream_feeds/lib/src/feeds_client.dart (2)

183-198: LGTM! Excellent documentation with practical example.

The connectionState getter documentation clearly explains its purpose and provides a helpful usage example showing how to handle different connection states.


200-206: LGTM! Appropriately scoped for testing.

The stateUpdateEvents getter is correctly marked @visibleForTesting and documented as test-only. This provides necessary access for testing state event flows without exposing it to production code.

Note: This aligns with the concern raised in state.dart about exporting @internal types. Since this getter is test-only, consider whether StateUpdateEvent types need to be in the main public exports.

packages/stream_feeds/test/state/activity_test.dart (1)

18-29: Event-based assertions on stateUpdateEvents are well-structured

Subscribing to tester.client.stateUpdateEvents with expectLater before issuing the API call, then await‑ing the expectation afterwards, gives you a clean, race‑free way to assert that the right StateUpdateEvent types (ActivityUpdated, CommentAdded/Updated/Deleted, PollUpdated, etc.) are emitted. The pattern is consistent across these tests and aligns nicely with the new state‑update event bus.

Also applies to: 115-129, 154-168, 422-433, 462-473, 519-541, 634-646, 686-706, 748-773, 826-845, 965-980, 1430-1446, 1486-1505

packages/stream_feeds/test/state/feed_test.dart (1)

69-86: State update event expectations are wired correctly through the public client

Across these tests you consistently assert on tester.client.stateUpdateEvents (e.g. FeedUpdated, FeedDeleted, ActivityAdded/Updated/Deleted, BookmarkAdded/Updated/Deleted, CommentAdded/Updated/Deleted, CommentReactionUpserted/Deleted, FollowAdded/Deleted, FeedMemberBatchUpdate, etc.) around the relevant API calls. This exercises the new StateUpdateEvent stream from the public StreamFeedsClient surface rather than internal notifiers, which matches the testing guidelines and the refactored architecture.

Also applies to: 113-124, 213-228, 264-280, 311-322, 345-359, 213-228, 983-997, 1040-1057, 1098-1115, 1335-1349, 1384-1405, 1445-1462, 1501-1512, 1549-1566, 1603-1620, 213-228

packages/stream_feeds/lib/src/client/feeds_client_impl.dart (1)

172-177: WebSocket → StateUpdateEvent mapping is clean and centralized

Subscribing once to events in the constructor and mapping each WsEvent through StateUpdateEvent.fromWsEvent into a shared MutableSharedEmitter<StateUpdateEvent> gives a clear, single source of truth for state updates. Using stateEvent?.let(_stateUpdateEmitter.tryEmit) safely skips unmapped events without throwing.

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_feeds/lib/src/client/feeds_client_impl.dart (1)

505-524: Fix scan method error on StateEmitter.

The pipeline error indicates that scan is not defined for StateEmitter. The code attempts to use RxDart's scan operator, but connectionState is a StateEmitter, not a Stream<T>.

🔎 Proposed fix

Convert the StateEmitter to a Stream before applying scan:

   Stream<void> get onReconnectEmitter {
-    return connectionState.scan(
-      (state, connectionStatus, i) => switch (connectionStatus) {
+    return connectionState.stream.scan<({bool wasDisconnected, bool reconnected})>(
+      ({bool wasDisconnected, bool reconnected} state, connectionStatus, i) => switch (connectionStatus) {
         Initialized() || Connecting() => (
             wasDisconnected: state.wasDisconnected,
             reconnected: false,
           ),
         Disconnecting() || Disconnected() => (
             wasDisconnected: true,
             reconnected: false,
           ),
         Connected() => (
             wasDisconnected: false,
             reconnected: state.wasDisconnected,
           ),
         _ => state,
       },
       (wasDisconnected: false, reconnected: false),
-    ).mapNotNull((state) => state.reconnected ? () : null);
+    ).mapNotNull<void>((state) => state.reconnected ? () : null);
   }

This also fixes the type inference warnings by explicitly providing types.

🤖 Fix all issues with AI Agents
In @packages/stream_feeds/lib/src/state/event/state_update_event.dart:
- Around line 27-31: The doc for StateUpdateEvent.fromWsEvent says it "Returns
[UnknownStateUpdateEvent] for unhandled event types" but the implementation
currently returns null; update the method (StateUpdateEvent.fromWsEvent) so that
for unhandled WsEvent types it returns an instance of UnknownStateUpdateEvent()
instead of null and keep the documentation as-is (or alternatively change the
doc to "returns null" if you prefer null semantics) — modify the return at the
unhandled branch to construct and return UnknownStateUpdateEvent and ensure
imports/types align.
🧹 Nitpick comments (1)
packages/stream_feeds/lib/src/state/event/state_update_event.dart (1)

330-854: Consider using @freezed for event data classes.

According to the coding guidelines, "Use @freezed for all data classes with required id fields and const constructors." The event classes (ActivityAdded, ActivityDeleted, BookmarkAdded, etc.) are data classes with required fields that would benefit from @freezed's features like immutability guarantees, copyWith, equality, and pattern matching support.

As per coding guidelines, consider refactoring these event classes to use @freezed mixed mode. This would provide better immutability guarantees and pattern matching capabilities throughout the state management layer.

Example refactoring for ActivityAdded
@freezed
class ActivityAdded with _$ActivityAdded implements StateUpdateEvent {
  const factory ActivityAdded({
    required FidScope scope,
    required ActivityData activity,
  }) = _ActivityAdded;
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 08932a0 and 5548fc1.

📒 Files selected for processing (4)
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
🧰 Additional context used
📓 Path-based instructions (6)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
{**/api/**/*.dart,**/*_api.dart,**/client/*.dart}

📄 CodeRabbit inference engine (.cursor/rules/stream-feeds-api.mdc)

{**/api/**/*.dart,**/*_api.dart,**/client/*.dart}: Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter
Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes
Use batch operations for bulk activity creation and updates to optimize API performance
Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Respect API rate limiting by implementing retry logic with retry-after headers and designing applications to handle rate limit responses gracefully
Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions
Use connection pooling and gzip compression for efficient HTTP connection management and reduced bandwidth when communicating with Stream Feeds API

Files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
packages/stream_feeds/test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/test/**/*.dart: Test through public APIs only, not internal StateNotifier implementations
Use HTTP interceptors instead of mocking repositories in tests
Mirror the lib/ structure in test/ directory organization

Files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
packages/stream_feeds/lib/src/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Use // for internal/private code documentation

Files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/src/state/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/state/**/*.dart: State classes must use @freezed with const constructors
State class naming convention: Use *State suffix for state classes (e.g., FeedState, ActivityListState)

Files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Design WebSocket integration for real-time updates through structured event handling and pattern matching
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Consider WebSocket real-time updates and implications in SDK architecture
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Mirror the `lib/` structure in `test/` directory organization

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/test/client/feeds_client_test.dart
  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Implement proper disposal patterns in Dart StateNotifiers and providers

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Implement proper disposal and cleanup patterns for resource management

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement proper resource management with disposal and cleanup patterns in Dart code

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/base_tester.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/ws/events/**/*.dart : Real-time event handlers must use `freezed` for type-safe event handling in WebSocket layer

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : StateNotifier naming convention: Use `*StateNotifier` suffix for StateNotifier implementations (e.g., `FeedStateNotifier`)

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : All repository methods must return `Result<T>` types for explicit error handling

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use early return patterns for validation and errors in repository methods

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Never throw exceptions in repositories - always return Result types

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Plan for StateNotifier reactive patterns when implementing state management in Dart

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Compose complex states from simpler freezed components using copyWith for immutable updates

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Implement reactive state management with StateNotifier-based state management and automatic notifications

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Design WebSocket integration for real-time updates through structured event handling and pattern matching

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds/lib/src/client/feeds_client_impl.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
🪛 GitHub Actions: legacy_version_analyze
packages/stream_feeds/lib/src/client/feeds_client_impl.dart

[error] 243-243: 'StateUpdateEvent' doesn't conform to the bound 'WsEvent' of the type parameter 'T'. Try using a type that is or is a subclass of 'WsEvent'. - type_argument_not_matching_bounds


[error] 244-244: 'StateUpdateEvent' doesn't conform to the bound 'WsEvent' of the type parameter 'T'. Try using a type that is or is a subclass of 'WsEvent'. - type_argument_not_matching_bounds


[error] 506-506: The method 'scan' isn't defined for the type 'StateEmitter'. Try correcting the name to the name of an existing method, or defining a method named 'scan'. - undefined_method


[warning] 3-3: Unused import: 'package:rxdart/rxdart.dart'. Try removing the import directive.


[warning] 507-507: The type of state can't be inferred; a type must be explicitly provided. Try specifying the type of the parameter.


[warning] 507-507: The type of connectionStatus can't be inferred; a type must be explicitly provided. Try specifying the type of the parameter.


[warning] 523-523: The type of state can't be inferred; a type must be explicitly provided. Try specifying the type of the parameter.


[info] 509-509: Method invocation or property access on a 'dynamic' target. Try giving the target a type.


[info] 518-518: Method invocation or property access on a 'dynamic' target. Try giving the target a type.


[info] 523-523: Method invocation or property access on a 'dynamic' target. Try giving the target a type.

packages/stream_feeds/lib/src/state/event/state_update_event.dart

[error] 24-24: Classes and mixins can only implement other classes and mixins. Try specifying a class or mixin, or remove the name from the list. - implements_non_class

⏰ 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). (2)
  • GitHub Check: build
  • GitHub Check: stream_feeds
🔇 Additional comments (7)
packages/stream_feeds/test/client/feeds_client_test.dart (1)

16-16: LGTM! Cleaner API for observing connection state.

The change from tester.client.connectionState.stream to tester.client.connectionState provides a more idiomatic API. The ConnectionStateEmitter getter returns a Stream-compatible type that properly supports expectLater with emitsInOrder, as confirmed by its usage with .listen(), .waitFor<T>(), and .scan() methods throughout the codebase. The tests correctly verify connection state transitions across all scenarios (successful connection, failed connection, and disconnection) and align with the guideline to test through public APIs.

packages/stream_feeds_test/lib/src/testers/base_tester.dart (3)

154-184: Excellent disposal pattern implementation!

The dispose() method follows best practices for lifecycle management in Dart:

  • The @mustCallSuper annotation ensures subclasses maintain the cleanup chain
  • Empty base implementation is appropriate since BaseTester itself holds no disposable resources
  • Comprehensive documentation with clear usage examples for both automatic and manual cleanup scenarios
  • Aligns with the PR's StateUpdateEvent refactoring by providing an explicit lifecycle hook for test harnesses

Based on learnings about proper disposal and cleanup patterns for resource management in Dart code.


194-194: LGTM!

Comment accurately reflects the addition of tester disposal cleanup registration.


214-218: Proper cleanup registration!

The disposal registration ensures dispose() is called after each test completes, even on test failure. The tearDown handlers execute in LIFO order:

  1. client.disconnect() (registered last, executes first)
  2. tester.dispose() (registered second, executes second)
  3. wsStreamController.close() (registered first, executes last)

This order correctly handles resource dependencies: disconnect the client first, then clean up tester-specific resources, finally close the underlying stream. The pattern aligns with the disposable resource management requirements.

packages/stream_feeds/lib/src/client/feeds_client_impl.dart (2)

272-273: LGTM!

Proper cleanup of the state update mapper subscription and emitter in the disconnect method. Resources are correctly disposed.


294-296: LGTM!

The factory methods are consistently updated to wire eventsEmitter: _stateUpdateEmitter throughout. This provides a uniform state update event flow across all state management components (Feed, FeedList, Activity, Comments, Bookmarks, Polls, etc.).

Also applies to: 304-305, 313-314, 325-333, 343-344, 372-373, 381-382, 390-391, 400-401, 410-411, 420-421, 429-430, 438-439, 447-448, 457-458

packages/stream_feeds/lib/src/state/event/state_update_event.dart (1)

24-25: No changes needed. The StateUpdateEvent sealed class correctly implements StreamEvent from the stream_core package (version ^0.3.3). The implementation is valid and functional, as evidenced by multiple subclasses extending it successfully throughout the codebase. No compilation errors exist.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/stream_feeds/lib/src/state/event/state_update_event.dart (2)

305-321: Minor: "Casted" is non-standard English.

The class PollVoteCasted uses "Casted" (line 822), though the standard past tense of "cast" is simply "cast." This likely mirrors the API event naming (api.PollVoteCastedFeedEvent), so keeping it aligned is reasonable for consistency. No action needed if this matches the backend naming convention.

Also applies to: 821-833


744-759: Consider mapping api.NotificationStatusResponse to a domain model.

The NotificationFeedUpdated event exposes api.NotificationStatusResponse? directly (line 755), while other events use domain models (e.g., ActivityData, FeedData). This introduces a generated API type into the domain-level event hierarchy. For consistency, consider creating a NotificationStatusData domain model with a .toModel() extension.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d04ea85 and 6716555.

📒 Files selected for processing (4)
  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/comments_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_feeds/lib/src/repository/comments_repository.dart
🧰 Additional context used
📓 Path-based instructions (5)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/src/repository/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/repository/**/*.dart: All repository methods must return Result<T> types for explicit error handling
Use early return patterns for validation and errors in repository methods
Use extension functions for API-to-domain model mapping in repositories
Never throw exceptions in repositories - always return Result types

Files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
packages/stream_feeds/lib/src/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Use // for internal/private code documentation

Files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
packages/stream_feeds/lib/src/state/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/state/**/*.dart: State classes must use @freezed with const constructors
State class naming convention: Use *State suffix for state classes (e.g., FeedState, ActivityListState)

Files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
🧠 Learnings (26)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Design WebSocket integration for real-time updates through structured event handling and pattern matching
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Consider WebSocket real-time updates and implications in SDK architecture
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : All repository methods must return `Result<T>` types for explicit error handling

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Never throw exceptions in repositories - always return Result types

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Request naming convention: Use `*Request` suffix for request classes (e.g., `FeedAddActivityRequest`)

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use early return patterns for validation and errors in repository methods

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : All repository methods must return Result types for explicit error handling

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Return `Result<T>` from all repository methods in Dart

Applied to files:

  • packages/stream_feeds/lib/src/repository/activities_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Follow Freezed 3.0 mixed mode syntax with `override` annotations for fields

Applied to files:

  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/src/repository/feeds_repository.dart
  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/ws/events/**/*.dart : Real-time event handlers must use `freezed` for type-safe event handling in WebSocket layer

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Maintain clean separation between public SDK APIs and internal implementation details

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/lib/src/state/event/state_update_event.dart
⏰ 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). (2)
  • GitHub Check: analyze
  • GitHub Check: stream_feeds
🔇 Additional comments (7)
packages/stream_feeds/lib/src/repository/feeds_repository.dart (1)

219-229: LGTM!

The unfollow method now correctly returns the removed FollowData, which aligns with the broader refactor to return domain models. The implementation follows repository guidelines using Result types and the .toModel() extension for mapping.

packages/stream_feeds/lib/src/repository/activities_repository.dart (2)

197-214: LGTM!

The composite record return type and documentation are well-structured. This change aligns with the PR's shift toward returning richer domain data for state update handling.


221-239: LGTM!

The updated documentation clearly describes the composite return structure with explicit field descriptions. The implementation correctly mirrors the addActivityReaction pattern.

packages/stream_feeds/lib/src/state/event/state_update_event.dart (4)

20-31: Well-structured sealed class hierarchy.

The sealed StateUpdateEvent enables exhaustive pattern matching for type-safe event handling. The factory method documentation now correctly states that null is returned for unhandled events, addressing the earlier inconsistency.


91-125: LGTM!

The upsert consolidation pattern using enforceUnique to differentiate between add (false) and update (true) operations is clean and reduces handler duplication downstream.


330-487: LGTM!

The event classes are well-structured with const constructors, required named parameters, and clear documentation. The design enables type-safe pattern matching for state update handling.


69-83: No action needed—the string comparison is correct per API specification.

The payload.value field is explicitly defined as a String type in the API model (not a boolean). The generated deserializer confirms this: value: json['value'] as String. Test cases consistently use lowercase 'true' and 'false' strings, and no JSON converters are applied to the value field. The comparison payload.value == 'true' correctly implements the API contract.

Likely an incorrect or invalid review comment.

@xsahil03x xsahil03x merged commit 491357d into main Jan 7, 2026
12 of 13 checks passed
@xsahil03x xsahil03x deleted the feat/state-update-events branch January 7, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants