Skip to content
Back to archipelago.banuacoder.com

Feature SDKs (Free)

state_management Free ​

Tier
Freeversion 0.1.2
Command
archipelago generate state_management
Generates
the BLoC, Cubit or notifier files and their tests for one feature, depending on stateManagement

Generate a state management layer (BLoC, Cubit, Riverpod, or Provider) for an existing feature module.

What it is ​

state_management is not a standalone feature brick — it's a scaffolding utility that generates presentation-layer state files (a Cubit, a Bloc, or a Riverpod/Provider notifier) for a feature you already have. Use it after feature_monorepo_skeleton (with stateManagement: none) to add a state class to a specific usecase, or to add another usecase's state to an existing feature.

Variables ​

VariableTypeDefaultDescription
stateManagementenumcubitState management solution: bloc, cubit, riverpod, provider
featureNamestringfeatureFeature name (e.g. auth, checkout, profile)
usecaseNamestring""Usecase to wire up (e.g. login, fetchProducts). Leave empty for a blank skeleton — naming then falls back to featureName
outputPathstring""Sub-path within the feature's presentation/ directory (e.g. login, home). Leave empty for the feature root

pre_gen.dart derives isBloc, isCubit, isRiverpod, isProvider, usesBloc (bloc or cubit), hasUsecase (true when usecaseName is non-empty), and the resolved name (usecaseName if set, else featureName) that all templates key off.

Usage ​

Interactive ​

bash
archipelago generate state_management

Non-interactive (CI) ​

bash
archipelago generate state_management --config my_config.json
json
{
  "stateManagement": "cubit",
  "featureName": "auth",
  "usecaseName": "login",
  "outputPath": "login"
}

Where files land ​

The brick's own templates are flat — bloc/, cubit/, or notifiers/ at the template root, with no presentation/ or outputPath segment baked into the file paths. Placing the output inside the target feature's lib/src/presentation/<outputPath>/ is done via the CLI's --output flag (archipelago generate state_management --output features/auth/auth_impl/lib/src/presentation/login), not by the brick itself. featureName/outputPath mainly drive the resolved name and the wiring instructions post_gen.dart prints — they don't relocate the generated files on their own.

Generated Structure ​

post_gen.dart deletes the directories for every variant except the one chosen:

VariantDirectoryFiles
blocbloc/<name>_bloc.dart, <name>_event.dart, <name>_state.dart, <name>_bloc_test.dart
cubitcubit/<name>_cubit.dart, <name>_state.dart, <name>_cubit_test.dart
riverpodnotifiers/<name>_notifier.dart, <name>_state.dart, <name>_notifier_test.dart
providernotifiers/<name>_notifier.dart, <name>_notifier_test.dart

Public API (generated code) ​

Templates key off a resolved name (usecaseName if set, else featureName, PascalCase/camelCase/snake_case as needed). The examples below resolve name to login (usecaseName: "login"), matching the CI config sample above.

Cubit variant (login_cubit.dart):

dart
class LoginCubit extends Cubit<LoginState> {
  LoginCubit(this._loginUseCase) // constructor param only when usecaseName is set
      : super(const LoginState.initial());

  Future<void> execute() async {
    emit(const LoginState.loading());
    try {
      await _loginUseCase();
      emit(const LoginState.loaded());
    } catch (e) {
      emit(LoginState.error(e.toString()));
    }
  }
}

Bloc variant's event file uses freezed, not a plain standalone class:

dart
part 'login_event.freezed.dart';

@freezed
sealed class LoginEvent with _$LoginEvent {
  const factory LoginEvent.started() = _Started;
  const factory LoginEvent.refreshed() = _Refreshed;
}

Riverpod variant uses the @riverpod codegen style (part 'login_notifier.g.dart'), requiring riverpod_generator and a build_runner pass:

dart
@riverpod
class LoginNotifier extends _$LoginNotifier {
  @override
  LoginState build() => const LoginState.initial();

  Future<void> execute() async { /* ... */ }
}

After generation ​

post_gen.dart prints variant-specific wiring instructions: the DI registration snippet, a widget consumption snippet, the barrel-export line to add to lib/src/presentation/presentation.dart, and (Riverpod only) the reminder to run:

bash
dart run build_runner build --delete-conflicting-outputs

Limitations / known issues ​

  • No CHANGELOG.md ships with this brick yet.
  • The bloc variant's event file is generated via freezed (part '<name>_event.freezed.dart'), which is a part file — this is worth noting because this repo's own conventions elsewhere describe bloc event/state files as "standalone (not part of)". Confirm this is intentional for this brick before relying on the standalone-file assumption.
  • outputPath does not relocate generated files by itself; passing the wrong --output value silently drops files at the wrong path with no validation.

Changelog ​

Run archipelago brick info state_management to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.