Enable refining the generic on a Mutation#4253
Enable refining the generic on a Mutation#4253rrousselGit merged 17 commits intorrousselGit:masterfrom
Conversation
WalkthroughAdds generic support for keyed mutations by making Mutation.call generic over a subtype of the result type, relaxes internal parent typing, updates equality for cross-type safety, and adds tests, docs examples, and a changelog entry reflecting the new keyed generic usage. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as Caller
participant Mutation as Mutation<ResultT>
participant Impl as MutationImpl<ChangedT>
Caller->>Mutation: call<ChangedT extends ResultT>(key)
Note right of Mutation #E8F8F5: Generic conversion\nproduces a typed keyed mutation
Mutation->>Impl: MutationImpl<ChangedT>._keyed((key, parent))
Note right of Impl #F6F8FF: _key stores (value, parent)\nparent typed as Mutation<Object?>
Impl-->>Caller: Mutation<ChangedT>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment — Out-of-scope changes
Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (19)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
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/riverpod/lib/src/core/mutations.dart (1)
89-95: Provider equality also blocks reuse across refined generics
_MutationProvider.operator ==uses_MutationProvider<ValueT>in the type check, which will be false for differentValueTeven ifmutationis equal. This causes separate provider entries for the same keyed mutation whenChangedTdiffers.Apply this diff:
@override bool operator ==(Object other) { - return other is _MutationProvider<ValueT> && mutation == other.mutation; + return other is _MutationProvider && mutation == other.mutation; }No change needed to
hashCodesince it’s already based onmutation.
🧹 Nitpick comments (4)
packages/riverpod/CHANGELOG.md (1)
9-10: Clarify API change with signature and snippetRecommend documenting the exact signature change and a tiny example for discoverability.
Apply this diff:
-- Made `Mutation.call` generic. - This allows for better compatibility with generic-returning functions (thanks to @TekExplorer) +- Made `Mutation.call` generic: `call<ChangedT extends ResultT>(Object? key) -> Mutation<ChangedT>`. + This enables refining a mutation's result type at the call site (thanks to @TekExplorer). + Example: + ```dart + final save = Mutation<Object?>(); + // Narrow the result type for this keyed usage: + final saveUser = save.call<User>(userId); + ```packages/riverpod/lib/src/core/mutations.dart (3)
336-346: Doc grammar fix (“These are”)Minor wording polish.
- /// This are passed using [call]. + /// These are passed using [call].
599-601: Doc typo (“You can also”)Minor typo.
-/// You cam also manually reset a mutation to its initial state using +/// You can also manually reset a mutation to its initial state using
411-413: Soundness of_keyparent type is fine given covariance, but add an assertionAt runtime, a mismatched parent would be catastrophic. Add a debug assert to ensure
thisis the parent when creating keyed instances.MutationImpl<ChangedT> call<ChangedT extends ResultT>(Object? key) { - return MutationImpl<ChangedT>._keyed((key, this), label: label); + assert(() { + // Sanity: parent must be `this`. + final parent = this; + return parent is Mutation<Object?>; + }()); + return MutationImpl<ChangedT>._keyed((key, this), label: label); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
packages/riverpod/CHANGELOG.md(1 hunks)packages/riverpod/lib/src/core/mutations.dart(2 hunks)
🔇 Additional comments (1)
packages/riverpod/lib/src/core/mutations.dart (1)
353-355: API: Genericcallis a good additionSignature looks right and aligns with the goal of refining the result type.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/riverpod/test/feature/mutation_test.dart (2)
41-44: Close subscriptions to avoid lingering listeners.Not required for correctness here, but closing them is cleaner and mirrors typical usage.
Apply this diff after the last expect:
@@ - expect(subDouble.read(), isMutationSuccess<double>(3.14)); + expect(subDouble.read(), isMutationSuccess<double>(3.14)); + sub.close(); + subInt.close(); + subDouble.close();
35-38: Tighten the comment wording.Clarify intent: it’s about instance equality when generic and key match.
Apply this diff:
- // shows that using the same generic - // with the same key will get the correct value + // Using the same generic and the same key yields the same mutation instance
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/riverpod/test/feature/mutation_test.dart(1 hunks)
⏰ 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). (20)
- GitHub Check: build (master, packages/riverpod)
- GitHub Check: build (master, packages/riverpod_annotation)
- GitHub Check: build (master, packages/flutter_riverpod/example)
- GitHub Check: build (master, examples/pub)
- GitHub Check: build (master, packages/riverpod_generator)
- GitHub Check: build (master, examples/marvel)
- GitHub Check: build (master, packages/flutter_riverpod)
- GitHub Check: build (stable, packages/flutter_riverpod/example)
- GitHub Check: build (master, examples/counter)
- GitHub Check: build (stable, packages/flutter_riverpod)
- GitHub Check: build (stable, examples/todos)
- GitHub Check: build (stable, packages/riverpod)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint)
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils)
- GitHub Check: check_generation
🔇 Additional comments (1)
packages/riverpod/test/feature/mutation_test.dart (1)
26-38: Nice coverage for generic/key identity.Good assertions showing distinct instances across generics and same-instance equality for identical generic+key.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
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)
website/docs/concepts2/mutations.mdx (1)
309-321: Fix variable name and incorrect run invocation in keyed example
- Variable used in ref.watch is
deleteMutation, but declared asdeleteTodoMutation.- Calling
runondeleteTodo(todo.id)is incorrect sincedeleteTodois the watched state, not the mutation. Callrunon the mutation instance with the same key.-/// final deleteTodoMutation = Mutation<void>(); +/// final deleteTodoMutation = Mutation<void>(); /// ... /// /// // You can pass a unique object to the mutation upon watching it. -/// final deleteTodo = ref.watch(deleteMutation(todo.id)); +/// final deleteTodo = ref.watch(deleteTodoMutation(todo.id)); /// ... /// /// onPressed: () { /// // Upon calling `run`, you will have to pass the same key as when /// // watching the mutation. -/// deleteTodo(todo.id).run(ref, (tsx) async { /* ... */ }); +/// deleteTodoMutation(todo.id).run(ref, (tsx) async { /* ... */ }); /// }
♻️ Duplicate comments (1)
packages/riverpod/lib/src/core/mutations.dart (1)
519-526: Equality currently blocks cross-generic keyed equality; consider ignoring type parameter in == for keyed instancesAs written,
operator ==requiresother is MutationImpl<ResultT>and_matchesT, so two keyed mutations with the same(parent, key)but differentChangedTwon’t be equal. This undermines the idea of “refining” the same keyed mutation across types (e.g.,mut<num>('k')vsmut<int>('k')), and may fragment caches/observers keyed by the mutation.Proposed change (keyed instances equal by
(parent,key)regardless of generic; unkeyed fallback remains identity):- bool _matchesT(Mutation<Object?> other) => other is Mutation<ResultT>; + // No longer needed if equality ignores generic for keyed instances.@override bool operator ==(Object other) { - if (other is! MutationImpl<ResultT> || !other._matchesT(this)) return false; - if (_key != null) return _key == other._key; + if (identical(this, other)) return true; + if (other is! MutationImpl) return false; + if (_key != null) return _key == (other as MutationImpl)._key; return super == other; }No change needed to
hashCodesince it already derives from_keywhen present.Note: To fully share provider instances across refined generics,
_MutationProvider.operator ==may also need to drop its generic constraint:- @override - bool operator ==(Object other) { - return other is _MutationProvider<ValueT> && mutation == other.mutation; - } + @override + bool operator ==(Object other) { + return other is _MutationProvider && mutation == other.mutation; + }If the intended design is to keep refined generics distinct, please confirm and we can drop this suggestion and add docs/tests clarifying the behavior.
🧹 Nitpick comments (3)
website/docs/concepts2/mutations.mdx (3)
40-48: Keyed mutation example: consider showing the watch/run flowThe snippet defines a keyed mutation instance but doesn’t illustrate how to listen/run it. Adding one line clarifies usage.
final removeTodo = Mutation<void>(); -final removeTodoWithId = removeTodo(todo.id); +final removeTodoWithId = removeTodo(todo.id); +// Later in a widget: +final state = ref.watch(removeTodoWithId); +// And when triggering: +removeTodoWithId.run(ref, (tsx) async { /* ... */ });
50-61: Grammar and casing tweaks; tighten example prose
- “api” → “API”
- “such as if” → “such as when”
-Sometimes, these mutations have a generic return type, -such as if an api response may have different response types +Sometimes, these mutations have a generic return type, +such as when an API response may have different response types based on the input parameters.
65-68: Wording nit: “our choice” → “your choice”Minor tone fix in user-facing docs.
-For this, we will need a <Link documentID="concepts2/refs" /> and pick a listening method of our choice +For this, we will need a <Link documentID="concepts2/refs" /> and pick a listening method of your choice (typically [Ref.watch]).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/riverpod/lib/src/core/mutations.dart(3 hunks)packages/riverpod/test/feature/mutation_test.dart(1 hunks)website/docs/concepts2/mutations.mdx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/riverpod/test/feature/mutation_test.dart
🧰 Additional context used
🪛 LanguageTool
website/docs/concepts2/mutations.mdx
[grammar] ~43-~43: There might be a mistake here.
Context: ...multiple instances of the same mutation, such as deleting a specific item in a li...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...se mutations have a generic return type, such as if an api response may have diff...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...sponse may have different response types based on the input parameters. ```dart f...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...nd pick a listening method of our choice (typically [Ref.watch]). A typical exa...
(QB_NEW_EN)
⏰ 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). (19)
- GitHub Check: build (master, packages/flutter_riverpod/example)
- GitHub Check: build (master, packages/flutter_riverpod)
- GitHub Check: build (master, examples/pub)
- GitHub Check: build (master, examples/random_number)
- GitHub Check: build (master, examples/stackoverflow)
- GitHub Check: build (stable, packages/riverpod_generator/integration/build_yaml)
- GitHub Check: build (stable, packages/riverpod)
- GitHub Check: build (master, examples/counter)
- GitHub Check: build (stable, examples/todos)
- GitHub Check: build (stable, packages/riverpod_generator)
- GitHub Check: build (stable, examples/marvel)
- GitHub Check: build (stable, examples/counter)
- GitHub Check: build (stable, examples/stackoverflow)
- GitHub Check: check_generation
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils)
🔇 Additional comments (3)
packages/riverpod/lib/src/core/mutations.dart (3)
354-355: API: Making Mutation.call generic is a good moveAllows refining the result type per key; annotation with @optionalTypeArgs is appropriate.
408-408: Internal key now stores parent as Mutation<Object?>This widens parent typing so keyed instances can originate from any parent mutation. Looks correct; ensure all tuple usages access
$1/$2consistently to avoid named-field drift.Would you like a quick grep script to verify only
$1/$2are used with_keyacross the file?
411-413: Generic call implementation LGTMReturning
MutationImpl<ChangedT>._keyed((key, this), ...)preserves parent identity and label; no unnecessary casts.
There was a problem hiding this comment.
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)
website/docs/concepts2/mutations.mdx (1)
101-102: Fix duplicated word and clarifyMinor grammar fix.
-// We perform a perform request using a Notifier. +// We perform a request using a Notifier.
♻️ Duplicate comments (1)
website/docs/concepts2/mutations.mdx (1)
52-52: Nice: snippet extracted and inlined via raw-loaderThis addresses the prior request to externalize code samples for compilation safety.
🧹 Nitpick comments (5)
website/docs/concepts2/mutations/listening.dart (1)
24-27: Verify WidgetStatePropertyAll vs MaterialStatePropertyAll compatibilityWidgetStatePropertyAll requires newer Flutter. If your min Flutter SDK is older, ButtonStyle.backgroundColor expects MaterialStateProperty<Color?>. Consider this fallback.
- backgroundColor: switch (addTodoState) { - MutationError() => const WidgetStatePropertyAll(Colors.red), - _ => null, - }, + backgroundColor: switch (addTodoState) { + MutationError() => const MaterialStatePropertyAll(Colors.red), + _ => null, + },website/docs/concepts2/mutations.mdx (4)
18-25: Polish punctuation and stray characterRemove the extra “!” and fix spacing before the semicolon.
-! + -...with UI concerns ; and it involves a lot of boilerplate code +...with UI concerns; and it involves a lot of boilerplate code
69-72: Tighten wording and capitalizationUse API (caps) and avoid the duplicated “such as”.
-Sometimes, these mutations have a generic return type, -such as if an api response may have different response types -based on the input parameters, such as with deserialization. +Sometimes, these mutations have a generic return type, +for example when an API response varies based on input parameters, +such as during deserialization.
87-89: Clarify: run is an instance methodThe narrative suggests passing a mutation to a static function. It’s invoked on the instance.
-To trigger a mutation, we can use [Mutation.run], pass our mutation, and provide an asynchronous callback +To trigger a mutation, call [Mutation.run] on your instance (e.g., addTodo.run) and provide an asynchronous callback
153-161: Confirm doc version pinningAll API links are pinned to 3.0.0‑dev.17. If the dev tag bumps, these will stale. Consider using latest or a shared version constant if that matches project conventions.
-[MutationPending]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/MutationPending-class.html +[MutationPending]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/MutationPending-class.html ... -[Ref.watch]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/riverpod/Ref/watch.html +[Ref.watch]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/watch.html
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
website/docs/concepts2/mutations.mdx(4 hunks)website/docs/concepts2/mutations/listening.dart(1 hunks)
🧰 Additional context used
🪛 LanguageTool
website/docs/concepts2/mutations.mdx
[grammar] ~5-~5: There might be a mistake here.
Context: ...mport CodeBlock from "@theme/CodeBlock"; import { trimSnippet } from "/src/compon...
(QB_NEW_EN)
[grammar] ~6-~6: There might be a mistake here.
Context: ...et } from "/src/components/CodeSnippet"; import listener from 'raw-loader!./mutat...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...multiple instances of the same mutation, such as deleting a specific item in a li...
(QB_NEW_EN)
[grammar] ~69-~69: There might be a mistake here.
Context: ...se mutations have a generic return type, such as if an api response may have diff...
(QB_NEW_EN)
[grammar] ~70-~70: There might be a mistake here.
Context: ...sponse may have different response types based on the input parameters, such as w...
(QB_NEW_EN)
⏰ 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). (19)
- GitHub Check: build (master, packages/hooks_riverpod/example)
- GitHub Check: build (master, packages/flutter_riverpod)
- GitHub Check: build (master, packages/riverpod_annotation)
- GitHub Check: build (master, examples/pub)
- GitHub Check: build (master, packages/flutter_riverpod/example)
- GitHub Check: build (master, examples/random_number)
- GitHub Check: build (master, examples/counter)
- GitHub Check: build (master, packages/riverpod)
- GitHub Check: build (master, examples/todos)
- GitHub Check: build (stable, packages/riverpod_annotation)
- GitHub Check: build (stable, packages/flutter_riverpod/example)
- GitHub Check: build (stable, examples/random_number)
- GitHub Check: build (stable, examples/pub)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils_tests)
- GitHub Check: check_generation
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils_tests)
🔇 Additional comments (2)
website/docs/concepts2/mutations/listening.dart (2)
16-17: Good use of Ref.watch for mutation stateClear, side‑effect free subscription to the mutation state.
39-42: Pending-state UI is succinct and correctConditional progress indicator based on MutationPending reads well.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
website/docs/concepts2/mutations.mdx (1)
5-12: Snippets extracted and imported correctly; listener path fix looks goodThe raw-loader imports point to dedicated .dart snippets, and the previous listener.dart → listening.dart issue is resolved.
Run to verify snippet files exist and imports match:
#!/bin/bash set -euo pipefail base="website/docs/concepts2/mutations" for f in listening.dart keyed.dart generic.dart triggering.dart switching.dart resetting.dart; do test -f "$base/$f" || { echo "Missing: $base/$f"; exit 1; } done # Ensure imports reference the exact filenames rg -nP $'^import\\s+\\w+\\s+from\\s+\\\'raw-loader!\\./mutations/(listening|keyed|generic|triggering|switching|resetting)\\.dart\\\';$' website/docs/concepts2/mutations.mdx
🧹 Nitpick comments (8)
website/docs/concepts2/mutations/triggering.dart (2)
45-45: Fix typo in comment.- // We perform a perform request using a Notifier. + // We perform a request using a Notifier.
35-54: Optionally await run to avoid re-entrancy and surface errors.Making onPressed async and awaiting run helps prevent double-taps during pending and propagates exceptions to Flutter’s error handler.
- return ElevatedButton( - onPressed: () { + return ElevatedButton( + onPressed: () async { // Trigger the mutation, and run the callback. // During the callback, we obtain a MutationTransaction (tsx) object // which we can use to access providers and perform operations. - addTodo.run(ref, (tsx) async { + await addTodo.run(ref, (tsx) async { // We use tsx.get to access providers within mutations. // This will keep the provider alive for the duration of the operation. final todoNotifier = tsx.get(todoNotifierProvider.notifier); - // We perform a perform request using a Notifier. + // We perform a request using a Notifier. final createdTodo = await todoNotifier.addTodo('Eat a cookie'); // We return the created todo. This enables our UI to show information // about the created todo, such as its ID/creation date/etc. return createdTodo; }); },website/docs/concepts2/mutations/generic.dart (1)
42-48: Return the created value to showcase generic return types.Returning the CreatedResponse from executeCreateTodo better demonstrates the new generic capability.
-Future<void> executeCreateTodo(MutationTarget ref) async { - await createTodo.run(ref, (tsx) async { +Future<CreatedResponse<Todo>> executeCreateTodo(MutationTarget ref) async { + return await createTodo.run(ref, (tsx) async { final client = tsx.get(apiProvider); final response = client.post('/todos', data: {'title': 'Eat a cookie'}); return CreatedResponse<Todo>.fromJson(response.data, Todo.fromJson); }); }website/docs/concepts2/mutations.mdx (5)
57-57: Specify code language for proper syntax highlightingAdd language="dart" to CodeBlock.
-<CodeBlock>{trimSnippet(listener)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(listener)}</CodeBlock>
59-76: Tighten phrasing, fix capitalization, and add code language; minor copyedits
- Capitalize “API”.
- Remove repetition (“such as … such as”).
- Minor grammar/punctuation.
- Add language="dart" to CodeBlock elements.
-### Scoping a mutation +### Scoping a mutation @@ -Sometimes, you may want to have multiple instances of the same mutation. +Sometimes, you may want multiple instances of the same mutation. @@ -This can include things like an id, or any other parameter that makes the mutation unique. +This can include an ID or any other parameter that makes the mutation unique. @@ -This is useful if you want to have multiple instances of the same mutation, -such as deleting a specific item in a list +This is useful when you want multiple instances of the same mutation, +such as deleting a specific item in a list. @@ -Simply call the mutation with the unique key: +Call the mutation with a unique key: @@ -<CodeBlock>{trimSnippet(keyed)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(keyed)}</CodeBlock> @@ -Sometimes, these mutations have a generic return type, -such as if an api response may have different response types -based on the input parameters, such as with deserialization. +Sometimes, mutations have a generic return type. For example, an API response +may deserialize into different types based on the input parameters. @@ -<CodeBlock>{trimSnippet(generic)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(generic)}</CodeBlock>
85-85: Add language to CodeBlockConsistent highlighting across snippets.
-<CodeBlock>{trimSnippet(triggering)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(triggering)}</CodeBlock>
97-97: Add language to CodeBlock-<CodeBlock>{trimSnippet(switching)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(switching)}</CodeBlock>
110-110: Add language to CodeBlock-<CodeBlock>{trimSnippet(resetting)}</CodeBlock> +<CodeBlock language="dart">{trimSnippet(resetting)}</CodeBlock>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
website/docs/concepts2/mutations.mdx(5 hunks)website/docs/concepts2/mutations/generic.dart(1 hunks)website/docs/concepts2/mutations/keyed.dart(1 hunks)website/docs/concepts2/mutations/resetting.dart(1 hunks)website/docs/concepts2/mutations/switching.dart(1 hunks)website/docs/concepts2/mutations/triggering.dart(1 hunks)
🧰 Additional context used
🪛 LanguageTool
website/docs/concepts2/mutations.mdx
[grammar] ~5-~5: There might be a mistake here.
Context: ...mport CodeBlock from "@theme/CodeBlock"; import { trimSnippet } from "/src/compon...
(QB_NEW_EN)
[grammar] ~6-~6: There might be a mistake here.
Context: ...et } from "/src/components/CodeSnippet"; import listener from 'raw-loader!./mutat...
(QB_NEW_EN)
[grammar] ~7-~7: There might be a mistake here.
Context: ...'raw-loader!./mutations/listening.dart'; import keyed from 'raw-loader!./mutation...
(QB_NEW_EN)
[grammar] ~8-~8: There might be a mistake here.
Context: ...rom 'raw-loader!./mutations/keyed.dart'; import generic from 'raw-loader!./mutati...
(QB_NEW_EN)
[grammar] ~9-~9: There might be a mistake here.
Context: ...m 'raw-loader!./mutations/generic.dart'; import triggering from 'raw-loader!./mut...
(QB_NEW_EN)
[grammar] ~10-~10: There might be a mistake here.
Context: ...raw-loader!./mutations/triggering.dart'; import switching from 'raw-loader!./muta...
(QB_NEW_EN)
[grammar] ~11-~11: There might be a mistake here.
Context: ...'raw-loader!./mutations/switching.dart'; import resetting from 'raw-loader!./muta...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...multiple instances of the same mutation, such as deleting a specific item in a li...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...se mutations have a generic return type, such as if an api response may have diff...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...sponse may have different response types based on the input parameters, such as w...
(QB_NEW_EN)
⏰ 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). (8)
- GitHub Check: Redirect rules - river-pod
- GitHub Check: Header rules - river-pod
- GitHub Check: Pages changed - river-pod
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils)
- GitHub Check: check_generation
🔇 Additional comments (4)
website/docs/concepts2/mutations/resetting.dart (1)
13-21: LGTM.Clear, minimal reset example consistent with the other snippets.
website/docs/concepts2/mutations.mdx (3)
53-53: Anchor reference clarifiedThe “typically [Ref.watch]” addition improves discoverability; link anchor is defined below. No changes needed.
120-120: Ref.watch anchor addedGood addition for direct API lookup. No action needed.
117-117: All pub.dev links are consistently using version 3.0.0-dev.17I’ve verified that every
https://pub.dev/documentation/riverpod/…link inwebsite/docs/concepts2/mutations.mdxpoints to version 3.0.0-dev.17. No updates are needed here.
| factory CreatedResponse.fromJson( | ||
| Map<String, Object?> json, | ||
| ValueT Function(Map<String, Object?>) fromJson, | ||
| ) { | ||
| return CreatedResponse(fromJson(json['data']! as Map<String, Object?>)); | ||
| } |
There was a problem hiding this comment.
Fix CreatedResponse.fromJson: currently reads a nested 'data' that isn’t present.
You pass response.data (already the payload), but fromJson tries to read json['data'] again—this will fail.
factory CreatedResponse.fromJson(
Map<String, Object?> json,
ValueT Function(Map<String, Object?>) fromJson,
) {
- return CreatedResponse(fromJson(json['data']! as Map<String, Object?>));
+ return CreatedResponse(fromJson(json));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| factory CreatedResponse.fromJson( | |
| Map<String, Object?> json, | |
| ValueT Function(Map<String, Object?>) fromJson, | |
| ) { | |
| return CreatedResponse(fromJson(json['data']! as Map<String, Object?>)); | |
| } | |
| factory CreatedResponse.fromJson( | |
| Map<String, Object?> json, | |
| ValueT Function(Map<String, Object?>) fromJson, | |
| ) { | |
| return CreatedResponse(fromJson(json)); | |
| } |
🤖 Prompt for AI Agents
In website/docs/concepts2/mutations/generic.dart around lines 9 to 14, the
CreatedResponse.fromJson factory incorrectly attempts to read json['data'] (a
nested key that doesn't exist because the caller already passes response.data);
change it to pass the supplied json directly to the fromJson converter (e.g.
call fromJson(json as Map<String, Object?>) or fromJson(json) with an
appropriate cast) and remove the ['data'] lookup so the factory uses the payload
already provided.
| /* SNIPPET START */ | ||
| final removeTodo = Mutation<void>(); | ||
| final removeTodoWithId = removeTodo(todo.id); |
There was a problem hiding this comment.
Close the snippet block.
Missing SNIPPET END will break docs extraction.
/* SNIPPET START */
final removeTodo = Mutation<void>();
final removeTodoWithId = removeTodo(todo.id);
+/* SNIPPET END */📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* SNIPPET START */ | |
| final removeTodo = Mutation<void>(); | |
| final removeTodoWithId = removeTodo(todo.id); | |
| /* SNIPPET START */ | |
| final removeTodo = Mutation<void>(); | |
| final removeTodoWithId = removeTodo(todo.id); | |
| /* SNIPPET END */ |
🤖 Prompt for AI Agents
In website/docs/concepts2/mutations/keyed.dart around lines 5 to 7, the snippet
block is not closed—there's a "SNIPPET START" but no corresponding "SNIPPET
END", which breaks docs extraction; add the missing "/* SNIPPET END */" (or the
project's expected snippet end marker) immediately after the shown code block to
properly close the snippet.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
website/docs/concepts2/mutations.mdx (2)
5-12: Snippets extracted and imports wired correctly.Raw-loader imports match the new .dart snippets. This addresses the earlier ask to extract snippets to dedicated files.
59-66: Good: new dedicated “Scoping a mutation” section placed under Listening.This implements the earlier suggestion to move this content into its own section under “Listening to mutations.”
🧹 Nitpick comments (4)
website/docs/concepts2/mutations.mdx (4)
23-24: Trailing “!” after image and awkward phrasing.Remove the extra exclamation and tighten the sentence.
-In short, mutations are to achieve effects such as this: -! +In short, mutations are used to achieve effects like this: +
27-29: Fix punctuation spacing.There should be no space before a semicolon.
-state of your provider with UI concerns ; and it involves a lot of boilerplate code +state of your provider with UI concerns; and it involves a lot of boilerplate code
72-75: Clarify wording and capitalize API; reduce repetition.“Simplify” the sentence and reflect the new ability to refine generics at call-site.
-Sometimes, these mutations have a generic return type, -such as if an api response may have different response types -based on the input parameters, such as with deserialization. +Sometimes, these mutations have a generic return type. For example, an API response may vary based on input parameters (deserialization), and you can refine the mutation’s generic at the call-site accordingly.
112-120: Prefer /latest docs links and add a link for Mutation.call.Hardcoding dev.17 makes the page stale quickly. Switch to /latest and add the missing [Mutation.call] reference to match the new feature.
-[MutationPending]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/MutationPending-class.html -[MutationError]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/MutationError-class.html -[MutationSuccess]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/MutationSuccess-class.html -[MutationIdle]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/MutationIdle-class.html -[Mutation.reset]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/Mutation/reset.html -[Mutation.run]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/Mutation/run.html -[Mutation]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/experimental_mutation/Mutation-class.html -[Notifier]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/riverpod/Notifier-class.html -[Ref.watch]: https://pub.dev/documentation/riverpod/3.0.0-dev.17/riverpod/Ref/watch.html +[MutationPending]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/MutationPending-class.html +[MutationError]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/MutationError-class.html +[MutationSuccess]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/MutationSuccess-class.html +[MutationIdle]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/MutationIdle-class.html +[Mutation.reset]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/Mutation/reset.html +[Mutation.run]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/Mutation/run.html +[Mutation.call]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/Mutation/call.html +[Mutation]: https://pub.dev/documentation/riverpod/latest/experimental_mutation/Mutation-class.html +[Notifier]: https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html +[Ref.watch]: https://pub.dev/documentation/riverpod/latest/riverpod/Ref/watch.htmlRun a quick docs-link check to ensure /latest works across the site before merging.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
website/docs/concepts2/mutations.mdx(5 hunks)website/docs/concepts2/mutations/switching.dart(1 hunks)website/docs/concepts2/mutations/triggering.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- website/docs/concepts2/mutations/switching.dart
- website/docs/concepts2/mutations/triggering.dart
🧰 Additional context used
🪛 LanguageTool
website/docs/concepts2/mutations.mdx
[grammar] ~5-~5: There might be a mistake here.
Context: ...mport CodeBlock from "@theme/CodeBlock"; import { trimSnippet } from "/src/compon...
(QB_NEW_EN)
[grammar] ~6-~6: There might be a mistake here.
Context: ...et } from "/src/components/CodeSnippet"; import listener from 'raw-loader!./mutat...
(QB_NEW_EN)
[grammar] ~7-~7: There might be a mistake here.
Context: ...'raw-loader!./mutations/listening.dart'; import keyed from 'raw-loader!./mutation...
(QB_NEW_EN)
[grammar] ~8-~8: There might be a mistake here.
Context: ...rom 'raw-loader!./mutations/keyed.dart'; import generic from 'raw-loader!./mutati...
(QB_NEW_EN)
[grammar] ~9-~9: There might be a mistake here.
Context: ...m 'raw-loader!./mutations/generic.dart'; import triggering from 'raw-loader!./mut...
(QB_NEW_EN)
[grammar] ~10-~10: There might be a mistake here.
Context: ...raw-loader!./mutations/triggering.dart'; import switching from 'raw-loader!./muta...
(QB_NEW_EN)
[grammar] ~11-~11: There might be a mistake here.
Context: ...'raw-loader!./mutations/switching.dart'; import resetting from 'raw-loader!./muta...
(QB_NEW_EN)
[grammar] ~19-~19: There might be a mistake here.
Context: ... objects which enable the user interface to react to state changes. A common use-...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...ser interface to react to state changes. A common use-case is displaying a loadin...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...ons are to achieve effects such as this: 
[style] ~23-~23: Using many exclamation marks might seem excessive (in this case: 8 exclamation marks for a text that’s 3819 characters long)
Context: ...ns are to achieve effects such as this:
! Without mutations, you would have to s...
(EN_EXCESSIVE_EXCLAMATION)
[grammar] ~65-~65: There might be a mistake here.
Context: ...multiple instances of the same mutation, such as deleting a specific item in a li...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...se mutations have a generic return type, such as if an api response may have diff...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...sponse may have different response types based on the input parameters, such as w...
(QB_NEW_EN)
⏰ 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). (18)
- GitHub Check: build (master, examples/todos)
- GitHub Check: build (stable, packages/riverpod_annotation)
- GitHub Check: build (stable, packages/riverpod_generator)
- GitHub Check: build (master, packages/riverpod/example)
- GitHub Check: build (master, packages/riverpod_generator)
- GitHub Check: build (master, packages/flutter_riverpod/example)
- GitHub Check: build (master, packages/riverpod)
- GitHub Check: build (master, packages/hooks_riverpod/example)
- GitHub Check: build (stable, packages/hooks_riverpod/example)
- GitHub Check: build (stable, packages/flutter_riverpod/example)
- GitHub Check: build (stable, packages/flutter_riverpod)
- GitHub Check: check_generation
- GitHub Check: build (stable, examples/todos)
- GitHub Check: riverpod_lint (stable, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (master, packages/riverpod_analyzer_utils_tests)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint_flutter_test)
- GitHub Check: riverpod_lint (master, packages/riverpod_lint)
- GitHub Check: riverpod_lint (stable, packages/riverpod_lint_flutter_test)
🔇 Additional comments (1)
website/docs/concepts2/mutations.mdx (1)
5-12: All mutation snippet files present and correctly referenced.
Verified that each of the six Dart snippets underwebsite/docs/concepts2/mutations/exists and is imported exactly once inmutations.mdx.
|
LGTM thanks! |
Related Issues
fixes #4252
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]).I have updated the
CHANGELOG.mdof the relevant packages.Changelog files must be edited under the form:
If this contains new features or behavior changes,
I have updated the documentation to match those changes.
Summary by CodeRabbit
New Features
Documentation
Tests