Skip to content

Instantly share code, notes, and snippets.

@rrousselGit
Last active May 3, 2026 15:53
Show Gist options
  • Select an option

  • Save rrousselGit/976b24b8b7668f6d840065f6f02a63f8 to your computer and use it in GitHub Desktop.

Select an option

Save rrousselGit/976b24b8b7668f6d840065f6f02a63f8 to your computer and use it in GitHub Desktop.
// ignore_for_file: prefer_relative_imports, public_member_api_docs, invalid_use_of_internal_member
import 'package:flutter_riverpod/experimental/mutation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/misc.dart';
final _fam = Family(
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
T _watch<T>(MutationTarget target, ProviderListenable<T> provider) {
switch (target) {
case Ref():
return target.watch(provider);
case WidgetRef():
return target.watch(provider);
case ProviderContainer():
throw UnsupportedError(
'Watching a provider from a ProviderContainer is not supported.',
);
case _:
throw UnsupportedError(
'Watching a provider from a ${target.runtimeType} is not supported.',
);
}
}
void _listen<T>(
MutationTarget target,
ProviderListenable<T> provider,
void Function(T? previous, T next) listener,
) {
switch (target) {
case Ref():
target.listen(provider, listener);
case WidgetRef():
target.listen(provider, listener);
case ProviderContainer():
target.listen(provider, listener);
case _:
throw UnsupportedError(
'Listening to a provider from a ${target.runtimeType} is not supported.',
);
}
}
T _read<T>(MutationTarget target, ProviderListenable<T> provider) {
switch (target) {
case Ref():
return target.read(provider);
case WidgetRef():
return target.read(provider);
case ProviderContainer():
return target.read(provider);
case _:
throw UnsupportedError(
'Reading a provider from a ${target.runtimeType} is not supported.',
);
}
}
extension FunctionalProvider<T> on T Function(Ref ref) {
Provider<T> get provider => Provider<T>.internal(
this,
from: _fam,
argument: (this,),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
T watch(MutationTarget target) => _watch(target, provider);
void listen(
MutationTarget target,
void Function(T? previous, T next) listener,
) => _listen(target, provider, listener);
T read(MutationTarget target) => _read(target, provider);
}
extension FunctionalFamily<T, Arg> on T Function(Ref ref, Arg arg) {
Provider<T> provider(Arg arg) => Provider<T>.internal(
(ref) => this(ref, arg),
from: _fam,
argument: (this, arg),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
T watch(MutationTarget target, Arg arg) => _watch(target, provider(arg));
void listen(
MutationTarget target,
Arg arg,
void Function(T? previous, T next) listener,
) => _listen(target, provider(arg), listener);
T read(MutationTarget target, Arg arg) => _read(target, provider(arg));
}
extension FunctionalFutureProvider<T> on Future<T> Function(Ref ref) {
FutureProvider<T> get provider => FutureProvider<T>.internal(
this,
from: _fam,
argument: (this,),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
AsyncValue<T> watch(MutationTarget target) => _watch(target, provider);
void listen(
MutationTarget target,
void Function(AsyncValue<T>? previous, AsyncValue<T> next) listener,
) => _listen(target, provider, listener);
AsyncValue<T> read(MutationTarget target) => _read(target, provider);
}
extension FunctionalFutureFamily<T, Arg> on T Function(Ref ref, Arg arg) {
FutureProvider<T> provider(Arg arg) => FutureProvider<T>.internal(
(ref) => this(ref, arg),
from: _fam,
argument: (this, arg),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
AsyncValue<T> watch(MutationTarget target, Arg arg) =>
_watch(target, provider(arg));
void listen(
MutationTarget target,
Arg arg,
void Function(AsyncValue<T>? previous, AsyncValue<T> next) listener,
) => _listen(target, provider(arg), listener);
AsyncValue<T> read(MutationTarget target, Arg arg) =>
_read(target, provider(arg));
}
extension ClassBasedProvider<NotifierT extends Notifier<StateT>, StateT>
on NotifierT Function() {
NotifierProvider<NotifierT, StateT> get provider =>
NotifierProvider<NotifierT, StateT>.internal(
this,
from: _fam,
argument: (this,),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
ProviderListenable<NotifierT> get notifier => provider.notifier;
StateT watch(MutationTarget target) => _watch(target, provider);
void listen(
MutationTarget target,
void Function(StateT? previous, StateT next) listener,
) => _listen(target, provider, listener);
StateT read(MutationTarget target) => _read(target, provider);
}
extension ClassBasedFamily<NotifierT extends Notifier<StateT>, StateT, ArgT>
on NotifierT Function(ArgT arg) {
NotifierProvider<NotifierT, StateT> provider(ArgT arg) =>
NotifierProvider<NotifierT, StateT>.internal(
() => this(arg),
from: _fam,
argument: (this, arg),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
ProviderListenable<NotifierT> notifier(ArgT arg) => provider(arg).notifier;
StateT watch(MutationTarget target, ArgT arg) =>
_watch(target, provider(arg));
void listen(
MutationTarget target,
ArgT arg,
void Function(StateT? previous, StateT next) listener,
) => _listen(target, provider(arg), listener);
StateT read(MutationTarget target, ArgT arg) => _read(target, provider(arg));
}
extension ClassBasedFutureProvider<
NotifierT extends AsyncNotifier<StateT>,
StateT
>
on NotifierT Function() {
AsyncNotifierProvider<NotifierT, StateT> get provider =>
AsyncNotifierProvider<NotifierT, StateT>.internal(
this,
from: _fam,
argument: (this,),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
ProviderListenable<NotifierT> get notifier => provider.notifier;
AsyncValue<StateT> watch(MutationTarget target) => _watch(target, provider);
void listen(
MutationTarget target,
void Function(AsyncValue<StateT>? previous, AsyncValue<StateT> next)
listener,
) => _listen(target, provider, listener);
AsyncValue<StateT> read(MutationTarget target) => _read(target, provider);
}
extension ClassBasedFutureFamily<
NotifierT extends AsyncNotifier<StateT>,
StateT,
ArgT
>
on NotifierT Function(ArgT arg) {
AsyncNotifierProvider<NotifierT, StateT> provider(ArgT arg) =>
AsyncNotifierProvider<NotifierT, StateT>.internal(
() => this(arg),
from: _fam,
argument: (this, arg),
name: null,
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
retry: null,
);
ProviderListenable<NotifierT> notifier(ArgT arg) => provider(arg).notifier;
AsyncValue<StateT> watch(MutationTarget target, ArgT arg) =>
_watch(target, provider(arg));
void listen(
MutationTarget target,
ArgT arg,
void Function(AsyncValue<StateT>? previous, AsyncValue<StateT> next)
listener,
) => _listen(target, provider(arg), listener);
AsyncValue<StateT> read(MutationTarget target, ArgT arg) =>
_read(target, provider(arg));
}
extension Compat<T> on ProviderListenable<T> {
T watch(MutationTarget target) => _watch(target, this);
void listen(
MutationTarget target,
void Function(T? previous, T next) listener,
) => _listen(target, this, listener);
T read(MutationTarget target) => _read(target, this);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment