패키지, 저장소 및 앱 카테고리 검색

패키지 상세v9.5.2

command_it

command_it는 `ValueListenable` 및 `Command` 디자인 패턴을 기반으로 상태를 관리하는 방법입니다. 이것은 flutter_command의 재브랜딩입니다.

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
5천
좋아요
35
Pub 점수
160

패키지 설치

flutter pub add command_it

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

command_it는 `ValueListenable`과 명령 디자인 패턴을 기반으로 한 상태 관리 솔루션으로, Flutter 앱에서 상태 변경을 깔끔하고 반응형 방식으로 처리할 수 있도록 제공합니다. 원래는 flutter_command로 알려져 있었으며, 비동기 작업 및 상태 업데이트를 관리하는 구조적인 접근 방식을 제공합니다. 이 패키지는 명령 내에 동작을 캡슐화함으로써 관심사의 분리를 촉진하여 코드를 더 테스트 가능하고 유지보수하기 쉽게 만듭니다. Flutter의 반응형 프레임워크와 원활하게 통합되며 모든 주요 플랫폼을 지원합니다.

사용 사례

  • API 호출과 같은 비동기 작업 관리
  • 폼 제출 처리
  • 취소/다시 실행 기능 구현
  • 여러 위젯 간 상태 변경 조율
  • 재사용 가능한 비즈니스 로직 계층 구축

주요 기능

  • ValueListenable를 통한 반응형 상태
  • 커맨드 패턴은 캡슐화된 작업을 위한 것
  • 로딩, 오류, 성공 상태에 대한 내장 지원
  • Flutter 위젯 트리와의 간편한 통합
  • 크로스 플랫폼 호환성

적합한 대상

  • 경량 상태 관리 대안을 찾는 개발자
  • UI와 비즈니스 로직 간의 명확한 분리를 원하는 팀
  • 예측 가능한 상태 전이가 필요한 프로젝트
  • 자주 비동기 작업을 수행하는 앱
  • 테스트 주도 개발 워크플로

고려 사항

  • 명령 패턴에 익숙하지 않은 새 사용자에게는 학습 곡선이 필요할 수 있습니다
  • 매우 간단한 상태 요구 사항에 적합하지 않습니다
  • 더 큰 상태 관리 솔루션과 비교해 생태계가 제한적
  • 완전한 앱 아키텍처를 위해 다른 도구와 함께 최적의 조합

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

command_it logo
Buy Me A Coffee
Sponsor

command_it codecov

📚 Complete documentation available at flutter-it.dev Check out the comprehensive docs with detailed guides, examples, and best practices!


🔄 Migration Notice (v9.0.0)

Important: Version 9.0.0 introduces new, clearer API naming. The old API is deprecated and will be removed in v10.0.0.

Quick Migration: execute() → run() | isExecuting → isRunning | canExecute → canRun

Run dart fix --apply to automatically update most usages.

Complete migration guide →


Command pattern for Flutter - wrap functions as observable objects with automatic state management

Commands replace async methods with reactive alternatives. Wrap your functions, get automatic loading states, error handling, and UI integration. No manual state tracking, no try/catch everywhere.

Call them like functions. React to their state. Simple as that.

Part of flutter_it — A construction set of independent packages. command_it works standalone or combines with watch_it for reactive UI updates.

Why Commands?

  • 🎯 Declarative — Wrap functions, get observable execution state automatically
  • ⚡ Automatic State — isRunning, value, errors tracked without manual code
  • 🛡️ Smart Error Handling — Route errors globally/locally with filters
  • 🔒 Built-in Protection — Prevents parallel execution automatically
  • 🎛️ Restrictions — Disable commands conditionally (auth, network, etc.)
  • 🧪 Testable — Easier to test than traditional async methods

Learn more about the benefits →

Quick Start

Installation

Add to your pubspec.yaml:

dependencies:
  command_it: ^9.0.2
  listen_it: ^5.3.3  # Required - commands build on ValueListenable
Basic Example
import 'package:command_it/command_it.dart';

// 1. Create a command that wraps your async function
class CounterManager {
  int _counter = 0;

  late final incrementCommand = Command.createAsyncNoParam<String>(
    () async {
      await Future.delayed(Duration(milliseconds: 500));
      _counter++;
      return _counter.toString();
    },
    initialValue: '0',
  );
}

// 2. Use it in your UI - command is a ValueListenable
class CounterWidget extends StatelessWidget {
  final manager = CounterManager();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // Shows loading indicator automatically while command runs
        ValueListenableBuilder<bool>(
          valueListenable: manager.incrementCommand.isRunning,
          builder: (context, isRunning, _) {
            if (isRunning) return CircularProgressIndicator();

            return ValueListenableBuilder<String>(
              valueListenable: manager.incrementCommand,
              builder: (context, value, _) => Text('Count: $value'),
            );
          },
        ),
        ElevatedButton(
          onPressed: manager.incrementCommand.run,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

That's it! The command automatically:

  • Prevents parallel execution
  • Tracks isRunning state
  • Publishes results
  • Handles errors

Full tutorial

Using CommandBuilder

Simplify your UI code with the built-in builder widget:

CommandBuilder<void, String>(
  command: manager.incrementCommand,
  whileRunning: (context, _, __) => CircularProgressIndicator(),
  onData: (context, value, _) => Text('Count: $value'),
  onError: (context, error, _, __) => Text('Error: $error'),
)

Key Features

Command Types

Create commands for any function signature:

Command Properties

Observe different aspects of execution:

  • value — Last successful result
  • isRunning — Async execution state
  • isRunningSync — Synchronous version for restrictions
  • canRun — Combined restriction and running state
  • errors — Stream of errors
  • results — CommandResult with all data at once
Error Handling

Declarative error routing with filters:

Advanced Features
Piping Commands

Chain commands together with the pipeToCommand() extension. When the source completes successfully, it automatically triggers the target command:

// Trigger refresh after save completes
saveCommand.pipeToCommand(refreshCommand);

// Transform result before passing to target
userIdCommand.pipeToCommand(fetchUserCommand, transform: (id) => UserRequest(id));

// Pipe from any ValueListenable - track execution state changes
longRunningCommand.isRunning.pipeToCommand(spinnerStateCommand);

The pipeToCommand() extension works on any ValueListenable, including commands, isRunning, results, or plain ValueNotifier. Returns a ListenableSubscription for manual cancellation if needed.

⚠️ Warning: Circular pipes (A→B→A) cause infinite loops. Ensure your pipe graph is acyclic.

Ecosystem Integration

Built on listen_it — Commands are ValueListenable objects, so they work with all listen_it operators (map, debounce, where, etc.).

// Register with get_it
di.registerLazySingleton(() => TodoManager());

// Use commands in your managers
class TodoManager {
  final loadTodosCommand = Command.createAsyncNoParam<List<Todo>>(
    () => api.fetchTodos(),
    [],
  );

  // Debounce search with listen_it operators
  final searchCommand = Command.createSync<String, String>((s) => s, '');

  TodoManager() {
    searchCommand.debounce(Duration(milliseconds: 500)).listen((term, _) {
      loadTodosCommand.run();
    });
  }
}

Want more? Combine with other flutter_it packages:

  • listen_it — Required dependency. ValueListenable operators and reactive collections.

  • Optional: watch_it — State management. Watch commands reactively without builders: watchValue((m) => m.loadCommand).

  • Optional: get_it — Service locator for dependency injection. Access managers with commands from anywhere: di<TodoManager>().

💡 flutter_it is a construction set — command_it works standalone. Add watch_it and get_it when you need reactive UI and dependency injection.

Explore the ecosystem →

AI-Assisted Development

This package ships an Agent Skill for AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex, Gemini CLI and others) in skills/command-it-expert/. It teaches them the critical rules, common patterns and anti-patterns of command_it. Install it into your project with the official Dart skills tool:

dart run skills@ get

For the ecosystem-wide skills (architecture guidance, feed/data-source patterns, overview) and the skills of the other flutter_it packages run:

dart run skills@ add flutter-it/flutter_it

Learn more about AI skills →

Learn More

📖 Documentation
💬 Community & Support

Contributing

Contributions are welcome! Please read the contributing guidelines before submitting PRs.

License

MIT License - see LICENSE file for details.


Part of the flutter_it ecosystem — Build reactive Flutter apps the easy way. No codegen, no boilerplate, just code.

카테고리

의존성

의존성 목록 3 개

소스 저장소

이 패키지를 사용하는 프로젝트