Skip to content

Conversation

@jgmontoya
Copy link
Contributor

@jgmontoya jgmontoya commented Oct 8, 2025

Description

Exposes the ensureAllSubscriptions method from the Rust core to the Flutter API layer. This method was added in PR#382 to the whitenoise crate and is now available for use in periodic background tasks to ensure all subscriptions (global and per-account) remain operational.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore
  • 🧪 Tests

Checklist

  • Run just precommit to ensure that formatting and linting are correct
  • Run just check-flutter-coverage to ensure that flutter coverage rules are passing
  • Updated the CHANGELOG.md file with your changes (if they affect the user experience)

Summary by CodeRabbit

  • New Features

    • Improved account relay status retrieval for more accurate, up-to-date reporting.
    • Added backend capability to ensure all subscriptions, improving reliability and reducing missed updates.
  • Refactor

    • Streamlined relay status retrieval flow (no user-facing behavior change).
  • Chores

    • Updated internal dependencies and regenerated native bindings.
    • Minor configuration formatting cleanup with no functional impact.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Walkthrough

Renamed relay status API from fetchRelayStatus to getAccountRelayStatuses across Dart/FRB/Rust layers and updated call sites. Added ensureAllSubscriptions API in Dart and Rust, with corresponding FRB codegen and dispatch updates. Minor pubspec formatting tweak and a Rust dependency revision in Cargo.toml.

Changes

Cohort / File(s) Summary
Provider wiring
lib/config/providers/relay_status_provider.dart
Switched relay status call to getAccountRelayStatuses(pubkey: ...); surrounding flow unchanged.
Dart relays API
lib/src/rust/api/relays.dart
Renamed fetchRelayStatusgetAccountRelayStatuses; added ensureAllSubscriptions() delegating to Rust; updated docs/comments.
Flutter Rust Bridge (Dart)
lib/src/rust/frb_generated.dart
Added wrappers: crateApiRelaysEnsureAllSubscriptions, crateApiRelaysGetAccountRelayStatuses; removed crateApiRelaysFetchRelayStatus; updated metas, codec paths, and function IDs.
Rust relays API
rust/src/api/relays.rs
Renamed fetch_relay_statusget_account_relay_statuses; added ensure_all_subscriptions() delegating to Whitenoise.
FRB codegen (Rust)
rust/src/frb_generated.rs
Regenerated dispatch/wiring to reflect new/renamed APIs; updated content hash and function mappings.
Rust deps
rust/Cargo.toml
Bumped whitenoise rev to a new commit hash; no feature changes.
Config formatting
pubspec.yaml
No-op formatting change to flutter_native_splash.web_image_mode line.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor UI as UI
  participant Provider as RelayStatusProvider
  participant DartAPI as Dart Relays API
  participant FRB as FRB (Dart↔Rust)
  participant RustAPI as Rust relays.rs
  participant Core as Whitenoise Core

  UI->>Provider: refreshStatuses(pubkey)
  Provider->>DartAPI: getAccountRelayStatuses(pubkey)
  DartAPI->>FRB: crateApiRelaysGetAccountRelayStatuses(pubkey)
  FRB->>RustAPI: get_account_relay_statuses(pubkey)
  RustAPI->>Core: query account relay statuses
  Core-->>RustAPI: Vec<(relay, status)>
  RustAPI-->>FRB: statuses
  FRB-->>DartAPI: List<(String, String)>
  DartAPI-->>Provider: statuses
  Provider-->>UI: render

  note over DartAPI,RustAPI: New API name used end-to-end
Loading
sequenceDiagram
  autonumber
  actor App as App
  participant DartAPI as Dart Relays API
  participant FRB as FRB (Dart↔Rust)
  participant RustAPI as Rust relays.rs
  participant Core as Whitenoise Core

  App->>DartAPI: ensureAllSubscriptions()
  DartAPI->>FRB: crateApiRelaysEnsureAllSubscriptions()
  FRB->>RustAPI: ensure_all_subscriptions()
  RustAPI->>Core: ensure_all_subscriptions()
  Core-->>RustAPI: Ok / Error (best-effort)
  RustAPI-->>FRB: Result<(), ApiError>
  FRB-->>DartAPI: Future<void>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • erskingardner
  • josefinalliende
  • codeswot

Poem

I thump the ground: new relays hum,
Subscriptions set—no crumbs to crumb. 🥕
Names hop lanes, a tidy course,
Bridge to Rust with gentle force.
Whiskers twitch—statuses align,
Nightcode sings, the signals fine.
Hop on—connections shine! ✨🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly highlights the primary change—exposing the new ensureAllSubscriptions method to the Flutter API—without unnecessary detail or noise, making it clear and relevant for reviewers scanning the repository history.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/expose-ensure-subscriptions

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90f67c1 and 1a77336.

⛔ Files ignored due to path filters (2)
  • pubspec.lock is excluded by !**/*.lock
  • rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • lib/config/providers/relay_status_provider.dart (1 hunks)
  • lib/src/rust/api/relays.dart (1 hunks)
  • lib/src/rust/frb_generated.dart (45 hunks)
  • pubspec.yaml (1 hunks)
  • rust/Cargo.toml (1 hunks)
  • rust/src/api/relays.rs (1 hunks)
  • rust/src/frb_generated.rs (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pubspec.yaml
  • rust/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)

**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...

Files:

  • lib/config/providers/relay_status_provider.dart
  • lib/src/rust/api/relays.dart
  • lib/src/rust/frb_generated.dart
🧬 Code graph analysis (1)
rust/src/frb_generated.rs (3)
rust/src/api/relays.rs (2)
  • ensure_all_subscriptions (73-79)
  • get_account_relay_statuses (41-51)
rust/src/api/accounts.rs (1)
  • export_account_nsec (93-101)
rust/src/api/messages.rs (1)
  • fetch_aggregated_messages_for_group (251-262)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Flutter CI
🔇 Additional comments (3)
lib/src/rust/frb_generated.dart (3)

1-2: Auto-generated file - codegen output looks correct.

This file is automatically generated by flutter_rust_bridge. The changes correctly expose the new ensureAllSubscriptions API and rename fetchRelayStatus to getAccountRelayStatuses as intended by the PR.


164-165: New relay management APIs added to public surface.

Two new methods have been correctly added to the public API:

  1. crateApiRelaysEnsureAllSubscriptions() - For ensuring all subscriptions remain operational (lines 164-165)
  2. crateApiRelaysGetAccountRelayStatuses({ required String pubkey }) - Returns relay statuses as a list of (URL, status) tuples (lines 185-187)

The signatures and return types are appropriate for their intended use cases.

Also applies to: 185-187


984-1010: Implementations follow consistent codegen patterns.

Both new method implementations follow the established flutter_rust_bridge pattern:

  • Proper FFI serialization setup
  • Correct funcId assignment (19 and 25 respectively)
  • Appropriate codec configuration with sse_decode_unit and sse_decode_list_record_string_string
  • Consistent error handling via sse_decode_api_error
  • Proper metadata (debugName, argNames)

The codegen output is consistent and correct.

Also applies to: 1176-1205


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.

Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
rust/src/frb_generated.rs (1)

3411-3499: Regenerate Dart bindings
The Rust dispatcher now routes func_ids 19 and 25, but lib/src/rust/frb_generated.dart is missing ensureAllSubscriptions and getAccountRelayStatuses. Re-run the codegen to include these methods.

🧹 Nitpick comments (5)
lib/src/rust/api.dart (1)

2-2: LGTM. Note: add CHANGELOG entry for exposed ensureAllSubscriptions and relay status API rename.

Keeps generated header in sync with FRB 2.10.0.

lib/config/providers/relay_status_provider.dart (1)

86-92: getAccountRelayStatuses returns a List of Dart records; optionally preflight subscriptions

  • getAccountRelayStatuses returns Future<List<(String, String)>> so for (final (url, status) in relayStatuses) remains valid.
  • Optional: add a best-effort call to ensureAllSubscriptions() before fetching statuses.
       _logger.info(
         'RelayStatusNotifier: Fetching relay statuses for pubkey: $activePubkey',
       );
+      // Best effort: ensure subscriptions are healthy before reading statuses
+      try {
+        await ensureAllSubscriptions();
+      } catch (_) {
+        // ignore: best-effort only
+      }
       // Fetch relay statuses using the Rust function
       final relayStatuses = await getAccountRelayStatuses(pubkey: activePubkey);
lib/src/rust/frb_generated.dart (3)

162-165: LGTM: ensureAllSubscriptions exposed and wired

API and impl look correct (no args, unit decode, proper const meta). Good addition for background maintenance flows. Based on learnings

  • Schedule it from background tasks (e.g., platform background workers) with sensible backoff.
  • Treat it as idempotent; avoid overlapping calls; surface errors to logs/telemetry.

Also applies to: 981-1009, 1005-1008


160-166: Docs/CHANGELOG

Public API surface changed (new relays methods and rename of status API). Please update CHANGELOG and any API docs.


183-186: Record support enabled; consider ergonomic Map wrapper

  • pubspec.yaml uses sdk: ^3.7.2, which supports Dart records.
  • Optional: add a helper in the relays API layer to convert List<(String, String)>Map<String, String> for easier consumption.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c5ddb2 and 90f67c1.

⛔ Files ignored due to path filters (2)
  • pubspec.lock is excluded by !**/*.lock
  • rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • lib/config/providers/relay_status_provider.dart (1 hunks)
  • lib/src/rust/api.dart (1 hunks)
  • lib/src/rust/api/accounts.dart (1 hunks)
  • lib/src/rust/api/error.dart (1 hunks)
  • lib/src/rust/api/groups.dart (1 hunks)
  • lib/src/rust/api/messages.dart (1 hunks)
  • lib/src/rust/api/metadata.dart (1 hunks)
  • lib/src/rust/api/relays.dart (2 hunks)
  • lib/src/rust/api/users.dart (1 hunks)
  • lib/src/rust/api/utils.dart (1 hunks)
  • lib/src/rust/api/welcomes.dart (1 hunks)
  • lib/src/rust/frb_generated.dart (46 hunks)
  • lib/src/rust/frb_generated.io.dart (1 hunks)
  • lib/src/rust/lib.dart (1 hunks)
  • pubspec.yaml (1 hunks)
  • rust/Cargo.toml (2 hunks)
  • rust/src/api/relays.rs (1 hunks)
  • rust/src/frb_generated.rs (13 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)

**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...

Files:

  • lib/src/rust/frb_generated.io.dart
  • lib/src/rust/api/utils.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/lib.dart
  • lib/config/providers/relay_status_provider.dart
  • lib/src/rust/api/relays.dart
  • lib/src/rust/api/metadata.dart
  • lib/src/rust/api.dart
  • lib/src/rust/frb_generated.dart
  • lib/src/rust/api/welcomes.dart
  • lib/src/rust/api/error.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/groups.dart
🧠 Learnings (2)
📚 Learning: 2025-08-08T13:39:00.500Z
Learnt from: CR
PR: parres-hq/whitenoise_flutter#0
File: .cursor/rules/flutter.mdc:0-0
Timestamp: 2025-08-08T13:39:00.500Z
Learning: Applies to **/*.dart : Use flutter_rust_bridge to access core functionality of the app.

Applied to files:

  • lib/src/rust/frb_generated.io.dart
  • lib/src/rust/api/utils.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • rust/Cargo.toml
  • lib/src/rust/lib.dart
  • lib/src/rust/api/relays.dart
  • lib/src/rust/api/metadata.dart
  • lib/src/rust/api.dart
  • rust/src/frb_generated.rs
  • lib/src/rust/frb_generated.dart
  • lib/src/rust/api/welcomes.dart
  • pubspec.yaml
  • lib/src/rust/api/error.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/groups.dart
📚 Learning: 2025-08-08T13:39:00.500Z
Learnt from: CR
PR: parres-hq/whitenoise_flutter#0
File: .cursor/rules/flutter.mdc:0-0
Timestamp: 2025-08-08T13:39:00.500Z
Learning: Applies to **/*.dart : Use the whitenoise rust crate (via flutter_rust_bridge) as the source of all data and only way to trigger changes in our data model.

Applied to files:

  • rust/Cargo.toml
  • lib/src/rust/api.dart
🧬 Code graph analysis (2)
rust/src/api/relays.rs (1)
rust/src/api/accounts.rs (2)
  • from (17-24)
  • from (39-53)
rust/src/frb_generated.rs (3)
rust/src/api/relays.rs (2)
  • ensure_all_subscriptions (73-79)
  • get_account_relay_statuses (41-51)
rust/src/api/accounts.rs (1)
  • export_account_nsec (93-101)
rust/src/api/messages.rs (1)
  • fetch_aggregated_messages_for_group (251-262)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Flutter CI
🔇 Additional comments (22)
lib/src/rust/api/users.dart (1)

2-2: Annotation update only — LGTM.

Generated header reflects FRB 2.10.0; nothing else changed.

lib/src/rust/api/utils.dart (1)

2-2: Annotation bump acknowledged — no functional changes.

All good.

lib/src/rust/api/error.dart (1)

2-2: Header version updated — LGTM.

Generated file; no code changes in this segment.

lib/src/rust/api/accounts.dart (1)

2-2: Confirm FRB 2.10.0 pin and relay API changes across Dart & Rust

  • pubspec.yaml uses flutter_rust_bridge 2.10.0
  • ensureAllSubscriptions & getAccountRelayStatuses present; fetchRelayStatus removed
  • verify Rust crate(s) Cargo.toml also pins flutter_rust_bridge to 2.10.0
lib/src/rust/api/groups.dart (1)

2-2: Header bump only — OK

Generated header matches FRB 2.10.0; no functional changes.

lib/src/rust/api/welcomes.dart (1)

2-2: Header bump only — OK

Generated header updated to FRB 2.10.0.

lib/src/rust/frb_generated.io.dart (1)

2-2: Header bump only — OK

IO bridge header reflects FRB 2.10.0; no functional changes here.

pubspec.yaml (1)

40-40: Approve FRB 2.10.0 pin and bindings cleanup: Dart and Rust deps correctly pinned to 2.10.0, no 2.11.x remnants, new relays API present, old API removed.

rust/Cargo.toml (1)

12-12: Confirm whitenoise API functions in commit
Manually verify that commit ae54a8d796af84c7c4357dcf7b317a930026ad09 of parres-hq/whitenoise (src/whitenoise/database/relays.rs) defines ensure_all_subscriptions and get_account_relay_statuses.

lib/src/rust/lib.dart (1)

2-2: FRB header version update — OK

No functional changes; aligns with the codegen downgrade to 2.10.0.

lib/src/rust/api/messages.dart (1)

2-2: FRB header version update — OK

No functional changes; consistent with generator downgrade.

lib/src/rust/api/metadata.dart (1)

2-2: FRB header version update — OK

No functional changes; consistent with generator downgrade.

rust/src/api/relays.rs (2)

41-51: Rename and delegation look correct

Resolves account, delegates to core get_account_relay_statuses, converts to (String, String). Async and error mapping are correct.


53-79: New ensure_all_subscriptions API — solid, minimal bridge

Exposes the core best‑effort checker with proper error mapping. Ready for background/periodic callers.

rust/src/frb_generated.rs (3)

740-774: Wire function for ensure_all_subscriptions added correctly.

No args, async wrapper, proper debug_name. Looks good.


971-1007: Wire function for get_account_relay_statuses looks correct.

Decodes pubkey and calls relays::get_account_relay_statuses. Matches Dart signature.


43-45: Dependency pinning verified: both Rust and Dart sides use flutter_rust_bridge 2.10.0 matching the codegen.

lib/src/rust/api/relays.dart (3)

20-23: Confirm no stale fetchRelayStatus callers. Run rg -nP --type=dart '\bfetchRelayStatus\b' to ensure all invocations are replaced with getAccountRelayStatuses.


24-44: Confirm generated binding exists and schedule with backoff

  • Verify that crateApiRelaysEnsureAllSubscriptions is present in the generated Dart API under RustLib.instance.api.
  • Invoke this via a background task with exponential backoff instead of from UI frames.

2-2: FRB version alignment confirmed: pubspec.yaml and Cargo.toml both specify 2.10.0, matching generated code markers.

lib/src/rust/frb_generated.dart (2)

370-396: FuncId remapping across file: ensure native side regenerated

Numerous funcId values changed after codegen downgrade and API additions. Verify Rust-side glue (wire/procedural macro output) is regenerated and included in this PR to avoid ABI mismatch at runtime.

Also applies to: 411-418, 545-556


2-2: FRB version and SDK constraint verified
All flutter_rust_bridge versions (2.10.0) align in pubspec.yaml, generated Dart files, Cargo.toml, and Rust code. Dart SDK ≥3.7.2 satisfies record support.

@jgmontoya jgmontoya merged commit 8b209bb into master Oct 9, 2025
2 checks passed
@jgmontoya jgmontoya deleted the feat/expose-ensure-subscriptions branch October 9, 2025 14:04
@coderabbitai coderabbitai bot mentioned this pull request Oct 17, 2025
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.

4 participants