{"id":23589058,"url":"https://github.com/flutterando/result_command","last_synced_at":"2025-10-09T12:32:54.265Z","repository":{"id":267542652,"uuid":"901581517","full_name":"Flutterando/result_command","owner":"Flutterando","description":"A command pattern implementation for Dart and Flutter using result_dart package.","archived":false,"fork":false,"pushed_at":"2025-06-12T14:40:57.000Z","size":315,"stargazers_count":7,"open_issues_count":3,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T12:32:15.104Z","etag":null,"topics":["dart","flutter"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/result_command","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flutterando.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-10T23:39:10.000Z","updated_at":"2025-06-28T13:19:08.000Z","dependencies_parsed_at":"2024-12-11T00:28:16.665Z","dependency_job_id":"a6fc4ccc-3ad6-467a-8ca6-2d15d35733b5","html_url":"https://github.com/Flutterando/result_command","commit_stats":null,"previous_names":["flutterando/result_command"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Flutterando/result_command","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fresult_command","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fresult_command/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fresult_command/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fresult_command/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flutterando","download_url":"https://codeload.github.com/Flutterando/result_command/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fresult_command/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001445,"owners_count":26083078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter"],"created_at":"2024-12-27T06:12:24.454Z","updated_at":"2025-10-09T12:32:54.258Z","avatar_url":"https://github.com/Flutterando.png","language":"Dart","readme":"# Result Command\n\n**Result Command** is a lightweight package that implements the **Command Pattern** in Flutter, enabling encapsulation of actions, state tracking, and result management.\n\n---\n\n## Installation\n\nAdd the package to your `pubspec.yaml`:\n```yaml\ndependencies:\n  result_command: x.x.x\n  result_dart: 2.x.x\n```\n\n---\n\n## How to Use\n\n### 1. Creating a Command\nCommands encapsulate actions and manage their lifecycle. Depending on the number of parameters your action requires, you can use:\n- **Command0**: For actions with no parameters.\n- **Command1**: For actions with one parameter.\n- **Command2**: For actions with two parameters.\n\nExample:\n```dart\nfinal fetchGreetingCommand = Command0\u003cString\u003e(\n  () async {\n    await Future.delayed(Duration(seconds: 2));\n    return Success('Hello, World!');\n  },\n);\n\nfinal calculateSquareCommand = Command1\u003cint, int\u003e(\n  (number) async {\n    if (number \u003c 0) {\n      return Failure(Exception('Negative numbers are not allowed.'));\n    }\n    return Success(number * number);\n  },\n);\n```\n\n---\n\n### 2. Listening to a Command\nCommands are `Listenable`, meaning you can react to their state changes:\n\n#### Using `addListener`\n```dart\nfetchGreetingCommand.addListener(() {\n  final status = fetchGreetingCommand.value;\n  if (status is SuccessCommand\u003cString\u003e) {\n    print('Success: ${status.value}');\n  } else if (status is FailureCommand\u003cString\u003e) {\n    print('Failure: ${status.error}');\n  }\n});\n```\n\n#### Using `ValueListenableBuilder`\n```dart\nWidget build(BuildContext context) {\n  return ListenableBuilder(\n    listenable: fetchGreetingCommand,\n    builder: (context, _) {\n      return switch (state) {\n        RunningCommand\u003cString\u003e() =\u003e CircularProgressIndicator(),\n        SuccessCommand\u003cString\u003e(:final value) =\u003e Text('Success: $value'),\n        FailureCommand\u003cString\u003e(:final error) =\u003e Text('Failure: $error'),\n        _ =\u003e ElevatedButton(\n          onPressed: () =\u003e fetchGreetingCommand.execute(),\n          child: Text('Fetch Greeting'),\n        ),\n      };\n    },\n  );\n}\n```\n\n#### Using `when` for Simplified State Handling\nThe `when` method simplifies state management by mapping each state to a specific action or value:\n```dart\nfetchGreetingCommand.addListener(() {\n  final status = fetchGreetingCommand.value;\n  final message = status.when(\n    data: (value) =\u003e 'Success: $value',\n    failure: (exception) =\u003e 'Error: ${exception?.message}',\n    running: () =\u003e 'Fetching...',\n    orElse: () =\u003e 'Idle',\n  );\n\n  print(message);\n});\n```\nThis approach ensures type safety and provides a clean way to handle all possible states of a command.\n\n---\n\n### 3. Executing a Command\nThe `execute()` method triggers the action encapsulated by the command. During execution, the command transitions through the following states:\n\n1. **Idle**: The initial state, indicating the command is ready to execute.\n2. **Running**: The state while the action is being executed.\n3. **Success**: The state when the action completes successfully.\n4. **Failure**: The state when the action fails.\n5. **Cancelled**: The state when the action is cancelled.\n\nEach command can only be executed one at a time. If another call to `execute()` is made while the command is already running, it will be ignored until the current execution finishes or is cancelled.\n\nExample:\n```dart\nfetchGreetingCommand.execute();\n```\n\n---\n\n### 4. Cancelling a Command\nCommands can be cancelled if they are in the `Running` state. When cancelled, the command transitions to the `Cancelled` state and invokes the optional `onCancel` callback.\n\nExample:\n```dart\nfinal uploadCommand = Command0\u003cvoid\u003e(\n  () async {\n    await Future.delayed(Duration(seconds: 5));\n  },\n  onCancel: () {\n    print('Upload cancelled');\n  },\n);\n\nuploadCommand.execute();\n\nFuture.delayed(Duration(seconds: 2), () {\n  uploadCommand.cancel();\n});\n```\n\n---\n\n### 5. Facilitators\n\nTo simplify interaction with commands, several helper methods and getters are available:\n\n#### State Check Getters\nThese getters allow you to easily check the current state of a command:\n```dart\n  if (command.isRunning) {\n    print('Command is idle and ready to execute.');\n  }\n```\n\n#### Cached Values\nTo avoid flickering or unnecessary updates in the UI, commands cache their last success and failure states:\n- **`getCachedSuccess()`**: Retrieves the cached value of the last successful execution, or `null` if no success is cached.\n  ```dart\n  final successValue = command.getCachedSuccess();\n  if (successValue != null) {\n    print('Last successful value: $successValue');\n  }\n  ```\n- **`getCachedFailure()`**: Retrieves the cached exception of the last failed execution, or `null` if no failure is cached.\n  ```dart\n  final failureException = command.getCachedFailure();\n  if (failureException != null) {\n    print('Last failure exception: $failureException');\n  }\n  ```\n\nThese facilitators improve code readability and make it easier to manage command states and results efficiently.\n\n---\n\n### 6. Filtering Command State\n\nThe `filter` method allows you to derive a new value from the command's state using a transformation function. This is useful for creating filtered or transformed views of the command's state.\n\n#### Example:\n```dart\nfinal filteredValue = command.filter\u003cString\u003e(\n  'Default Value',\n  (state) {\n    if (state is SuccessCommand\u003cString\u003e) {\n      return 'Success: ${state.value}';\n    } else if (state is FailureCommand\u003cString\u003e) {\n      return 'Error: ${state.error}';\n    }\n    return null; // Ignore other states.\n  },\n);\n\nfilteredValue.addListener(() {\n  print('Filtered Value: ${filteredValue.value}');\n});\n```\n\nThis method simplifies state management by allowing you to focus on specific aspects of the command's state.\n\n---\n\n### 7. CommandRef\n\nThe `CommandRef` class allows you to create commands that listen to changes in one or more `ValueListenables` and execute actions based on derived values.\n\n#### Example:\n```dart\nfinal listenable = ValueNotifier\u003cint\u003e(0);\n\nfinal commandRef = CommandRef\u003cint, int\u003e(\n  (ref) =\u003e ref(listenable),\n  (value) async =\u003e Success(value * 2),\n);\n\ncommandRef.addListener(() {\n  final status = commandRef.value;\n  if (status is SuccessCommand\u003cint\u003e) {\n    print('Result: ${status.value}');\n  }\n});\n\nlistenable.value = 5; // Executes the command with the value 5.\n```\n\n#### Features:\n- Automatically listens to changes in `ValueListenables`.\n- Executes the action whenever the derived value changes.\n- Cleans up listeners when disposed.\n\nThis class is ideal for scenarios where commands need to react dynamically to external state changes.\n\n\n## Documentation\n\nFor advanced examples and detailed documentation, visit:\n- [Examples](example/)\n- [GitHub Wiki](https://github.com/seu-repo/result_command/wiki)\n\n---\n\n## Contribute\n\nWe welcome contributions! Feel free to report issues, suggest features, or submit pull requests.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fresult_command","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflutterando%2Fresult_command","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fresult_command/lists"}