cool_bedrock 1.0.0 copy "cool_bedrock: ^1.0.0" to clipboard
cool_bedrock: ^1.0.0 copied to clipboard

A bedrock package providing the blueprints and abstract definitions necessary to build a scalable and maintainable Dart/Flutter application.

cool_bedrock #

A bedrock package providing the blueprints and abstract definitions necessary to build a scalable and maintainable Dart/Flutter application.

Pub Version Pub Likes Pub Points Pub Downloads Dart SDK Version License codecov


✨ Features #

  • πŸ›οΈ Formalized Architecture: Strict base contracts for all layers: Entity, Params, AppService, and Codable.
  • 🎯 Domain Logic (Use Cases): Typified UseCase hierarchy for commands and queries, including assisted flow management (UseCaseHandler).
  • πŸ›‘οΈ Functional Error Handling: Leverages the functional types Either<Failure, T> and Option
  • πŸ›‘ Typed Errors: Coherent error structure using sealed base classes: Issue, Failure (business logic), RepositoryError, and DataSourceException (technical/infrastructure).
  • πŸ”„ Reactive Services: Base classes for creating services that manage state using BehaviorSubject, PublishSubject, and periodic execution logic (Timer).
  • πŸ§ͺ Immutability & Testability: All core domain structures (Entity, Params) are immutable and comparable (Equatable).

πŸš€ Installation #

Add the package to your pubspec.yaml:

dependencies:
  cool_bedrock: ^1.0.0

Then run:

dart pub get

πŸ“† Usage #

Basic usage #

import 'package:cool_bedrock/cool_bedrock.dart';

1. Creating the Use Case #

This example demonstrates how to implement a UseCase, defining its specific Failure and parameter validation:

// 1. Define the specific Failure for this domain
sealed class FetchUserFailure extends Failure{
  const FetchUserFailure();
}
final class InvalidUserFailure extends FetchUserFailure {
  const InvalidUserFailure() : super(message: 'Invalid User ID provided.');
}
final class InvalidParamsUserFailure extends FetchUserFailure {
  const InvalidParamsUserFailure() : super(message: 'Invalid parameters provided.');
}

// 2. Implement the UseCase contract
final class FetchUserUseCase
    extends UseCase<UserEntity, FetchUserParams, FetchUserFailure> {
  const FetchUserUseCase(this.repository);

  final UserRepository repository;

  // Called automatically if params.isNotValid is true.
  @override
  FetchUserFailure onInvalidParams() => const InvalidParamsUserFailure();

  @override
  Future<Either<FetchUserFailure, UserEntity>> execute(
      FetchUserParams params) async {
    // Core logic goes here. Mappers and Repositories are typically called here.
    try {
      final user = await repository.fetch(params.userId);
      return Right(user); // Success
    } catch (e) {
      // Map low-level errors to high-level domain failures
      return const Left(InvalidUserFailure()); // Failure
    }
  }
}

final class FetchUserUseCaseHandle
    extends
        UseCaseHandler<
          UserEntity,
          AuthParams,
          FetchUserFailure,
          RepositoryValue
        > {
  const LoginUsecaseHandler({
    required LoginRepository repository,
  });

  final UserRepository repository;

  // Called automatically if params.isNotValid is true.
  @override
  FetchUserFailure onInvalidParams() => const InvalidParamsUserFailure();

  //Obtain repository values. Multiple repository can be call.
  @override
  Future<RepositoryValue> obtainValues(
    Resolver<FetchUserFailure> $,
    AuthParams params,
  ) async {
    final user = await $(
      getValue(
        () => repository.fetch(params.userId),
      ),
    );
    return user;
  }

  @override
  UserEntity transformation(
    RepositoryValue values,
  ) {
    if(values.name == null || values.name.isEmpty){
      throw const UsecaseException(InvalidUserFailure());
    }
    //Can throw exception of any kind and it will be control by [wrapError]
    return values.toEntity()
  }

  @override
  FetchUserFailure wrapError(Object error, StackTrace stackTrace) {
    return const InvalidUserFailure();
  }
}

2. Execution and Error Handling #

// Execution with valid parameters
final validParams = const FetchUserParams('user_123');
final validResult = await fetchUserUsecase.call(validParams);

validResult.fold(
  // LEFT side (Failure)
  (failure) => print('Error: ${failure.message}'),
  // RIGHT side (Success)
  (user) => print('Fetched User: ${user.name}'),
);

πŸ’‘ Reactive Services Example #

The base services provide lifecycle control and reactivity. Here's a service that periodically updates a counter:

import 'package:cool_bedrock/cool_bedrock.dart';
import 'dart:async';

final class HeartbeatService extends TimerAndBehaviorService<int> {
  HeartbeatService()
      : super(periodicDuration: const Duration(seconds: 10));

  int _counter = 0;

  @override
  Future<void> work() async {
    // Logic that runs every 10 seconds
    _counter++;
    // Emit the new value to all subscribers
    add(_counter);
  }

  // start(), stop(), and dispose() logic is inherited and controlled externally.
}

πŸ“š API Reference #

Check the full API reference, including all generic types and abstract classes, on pub.flutter-io.cn β†’ cool_bedrock.


Authors & Maintainers #

This project was created and is primarily maintained by:

🀝 Contributing #

Contributions are welcome!

  • Open issues for bugs or feature requests
  • Fork the repo and submit a PR
  • Run dart format and dart test before submitting

πŸ§ͺ Testing #

To run tests and see code coverage:

dart test

πŸ“„ License #

MIT Β© 2025 Coolosos

0
likes
150
points
78
downloads

Publisher

unverified uploader

Weekly Downloads

A bedrock package providing the blueprints and abstract definitions necessary to build a scalable and maintainable Dart/Flutter application.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#architecture #clean-architecture #domain-driven-design #functional-programming #core

Documentation

API reference

License

MIT (license)

Dependencies

equatable, fpdart, meta, rxdart

More

Packages that depend on cool_bedrock