Skip to content

Instantly share code, notes, and snippets.

@Luckey-Elijah
Last active July 20, 2022 18:07
Show Gist options
  • Save Luckey-Elijah/9d35526acea0650403039e1f2b8c0431 to your computer and use it in GitHub Desktop.
Save Luckey-Elijah/9d35526acea0650403039e1f2b8c0431 to your computer and use it in GitHub Desktop.
Cached Streamable class
import 'dart:async';
import 'package:meta/meta.dart';
/// {@template cached_streamable}
/// Extend this class for a streamable, single-data type repository.
/// {@endtemplate}
abstract class CachedStreamable<T> {
/// {@macro cached_streamable}
CachedStreamable({
required T initialState,
bool broadcast = false,
}) : _state = initialState,
_controller =
broadcast ? StreamController<T>.broadcast() : StreamController<T>();
/// Currently stored value of the state.
T _state;
/// The controller in use.
final StreamController<T> _controller;
/// Getter for the state.
@protected
T get value => _state;
/// Setter for the state and adds the value to the controller.
@protected
set value(T newValue) {
if (_state == newValue) return;
_controller.add(_state = newValue);
}
/// Listen to the changes when [value] is updated.
/// This will yield the currently stored value when listened to and then yield
/// all future changes to the state.
Stream<T> get status async* {
yield _state;
yield* _controller.stream;
}
/// Close controller and clean up the resources used.
@mustCallSuper
FutureOr<void> close() => _controller.close();
}
import 'dart:async';
import 'cached_streamable.dart';
enum AuthStatus {
unknown,
authenticated,
unauthenticated,
}
class AuthenticationRepository extends CachedStreamable<AuthStatus> {
AuthenticationRepository() : super(initialState: AuthStatus.unknown);
Future<void> login({
required String email,
required String password,
}) async {
await Future<void>.delayed(const Duration(seconds: 2));
value = AuthStatus.authenticated;
}
Future<void> logout() async {
await Future<void>.delayed(const Duration(seconds: 2));
value = AuthStatus.unauthenticated;
}
}
Future<void> main() async {
final repo = AuthenticationRepository();
// prints: AuthStatus.unknown
final subscription = repo.status.listen(print);
// prints: AuthStatus.authenticated
await repo.login(
email: 'email',
password: 'password',
);
// prints: AuthStatus.unauthenticated
await repo.logout();
await repo.close();
await subscription.cancel();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment