bloc_ai 1.1.3 copy "bloc_ai: ^1.1.3" to clipboard
bloc_ai: ^1.1.3 copied to clipboard

BlocAI: a Flutter package for strict Bloc clean architecture.

BlocAI #

bloc_ai is a Flutter package that enforces an MVP architecture powered by flutter_bloc.

The package centers around an extendable BaseApp (a MaterialApp root), which wires presenter lifecycle, view attachment, and Bloc/Cubit state propagation at app entry.

What this package enforces #

  • One-way flow: View -> Presenter intent -> Bloc/Cubit state -> View render
  • Typed contracts for MvpState, MvpView, and MvpPresenter
  • A BlocPresenter base class that listens to StateStreamableSource
  • Lifecycle hooks (onInit, onDispose, attach/detach view) in a consistent path

Quick start (BaseApp first) #

class CounterState extends MvpState {
  const CounterState(this.value);
  final int value;
}

class CounterView implements MvpView<CounterState> {
  @override
  void render(CounterState state) {}
}

class CounterCubit extends Cubit<CounterState> {
  CounterCubit() : super(const CounterState(0));
  void increment() => emit(CounterState(state.value + 1));
}

class CounterPresenter extends BlocPresenter<CounterView, CounterState> {
  CounterPresenter(this.cubit, this.repository) : super(cubit);
  final CounterCubit cubit;
  final CounterRepository repository;

  void onIncrementTap() => cubit.setCount(repository.incrementFrom(cubit.state.value));
}
class AppRoot extends BaseApp<CounterPresenter, CounterView, CounterState> {
  const AppRoot({super.key});

  @override
  List<RepositoryProvider<Object?>> get repositoryProviders =>
      <RepositoryProvider<Object?>>[
        RepositoryProvider<Object?>.value(value: CounterRepository()),
      ];

  @override
  List<BlocProviderSingleChildWidget> get blocProviders =>
      <BlocProviderSingleChildWidget>[
        BlocProvider<CounterCubit>(create: (_) => CounterCubit()),
      ];

  @override
  CounterPresenter createPresenter(BuildContext context) {
    final cubit = BlocProvider.of<CounterCubit>(context);
    final repo = RepositoryProvider.of<Object?>(context) as CounterRepository;
    return CounterPresenter(cubit, repo);
  }

  @override
  CounterView createView(BuildContext context) => CounterView();

  @override
  Widget buildHome(BuildContext context, CounterState state, CounterPresenter presenter) {
    return Scaffold(
      body: TextButton(
        onPressed: presenter.onIncrementTap,
        child: Text('Count: ${state.value}'),
      ),
    );
  }
}
feature/
  data/
  domain/
  presentation/
    bloc/
    presenter/
    view/

Do and don't #

  • Do keep user intents in presenter methods.
  • Do keep business state in Bloc/Cubit.
  • Do keep rendering concerns in MvpView and widgets.
  • Do extend BaseApp so architecture enforcement starts from app entry.
  • Don't call repositories directly from widgets.
  • Don't mutate UI state outside Bloc/Cubit transitions.

Example #

A minimal runnable example app lives in example/ and shows BaseApp + BaseBloc + BasePage together.

AI Enforcement Contracts #

Machine-readable enforcement files for AI tools are available in ai/:

  • ai/architecture_rules.json
  • ai/feature_scaffold_contract.json
0
likes
150
points
26
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

BlocAI: a Flutter package for strict Bloc clean architecture.

Homepage
Repository (GitHub)
View/report issues

Topics

#flutter #architecture #bloc #mvp

License

MIT (license)

Dependencies

flutter, flutter_bloc, meta, provider

More

Packages that depend on bloc_ai