diff --git a/README.md b/README.md index e981215..9a84207 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Flutter Rocket +# logo-2 Flutter Rocket **The ultimate power-up for your Flutter state management and API integration.** @@ -26,9 +26,12 @@ Flutter Rocket is a high-performance, lightweight state management and API integ | Package | Version | Description | | --- | --- | --- | | [flutter_rocket](https://pub.dev/packages/flutter_rocket) | [![pub package](https://img.shields.io/pub/v/flutter_rocket.svg)](https://pub.dev/packages/flutter_rocket) | Core bundle for Flutter. | -| [rocket_model](https://pub.dev/packages/rocket_model) | [![pub package](https://img.shields.io/pub/v/rocket_model.svg)](https://pub.dev/packages/rocket_model) | Base model and state logic. | +| [rocket_model](https://pub.dev/packages/rocket_model) | [![pub package](https://img.shields.io/pub/v/rocket_model.svg)](https://pub.dev/packages/rocket_model) | A type‑safe, reactive model layer. | | [rocket_client](https://pub.dev/packages/rocket_client) | [![pub package](https://img.shields.io/pub/v/rocket_client.svg)](https://pub.dev/packages/rocket_client) | HTTP client with caching. | | [rocket_view](https://pub.dev/packages/rocket_view) | [![pub package](https://img.shields.io/pub/v/rocket_view.svg)](https://pub.dev/packages/rocket_view) | UI state management widgets. | +| [rocket_mini_view](https://pub.dev/packages/rocket_mini_view) | [![pub package](https://img.shields.io/pub/v/rocket_mini_view.svg)](https://pub.dev/packages/rocket_mini_view) | A tiny, reactive widget. | +| [rocket_singleton](https://pub.dev/packages/rocket_singleton) | [![pub package](https://img.shields.io/pub/v/rocket_singleton.svg)](https://pub.dev/packages/rocket_singleton) | Fast, type‑safe in‑memory storage. | +| [rocket_cache](https://pub.dev/packages/rocket_cache) | [![pub package](https://img.shields.io/pub/v/rocket_cache.svg)](https://pub.dev/packages/rocket_cache) | A persistence and caching layer. | | [rocket_cli](https://pub.dev/packages/rocket_cli) | [![pub package](https://img.shields.io/pub/v/rocket_cli.svg)](https://pub.dev/packages/rocket_cli) | CLI for model generation. | --- @@ -53,8 +56,9 @@ Flutter Rocket is a high-performance, lightweight state management and API integ ## 🎨 Graphic Tutorial -![Flutter Rocket Architecture](https://github.com/JahezAcademy/flutter_rocket/blob/dev/images/flutter_rocket_schema.jpg) -[Explore the Miro Board](https://miro.com/app/board/uXjVPndHj2s=/?share_link_id=307293362528) +![Flutter Rocket Architecture](https://github.com/user-attachments/assets/b60a34bd-e480-4e6b-81af-1bb9905c0017) + +[Explore the Miro Board](https://miro.com/app/board/uXjVJal1g3o=/?share_link_id=335195782321) --- diff --git a/packages/flutter_rocket/pubspec.yaml b/packages/flutter_rocket/pubspec.yaml index 738f44b..e161e57 100644 --- a/packages/flutter_rocket/pubspec.yaml +++ b/packages/flutter_rocket/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_rocket description: Powerful package for state management & request. version: 0.0.9 -repository: https://github.com/JahezAcademy/flutter_rocket/flutter_rocket +repository: https://github.com/JahezAcademy/flutter_rocket issue_tracker: https://github.com/JahezAcademy/flutter_rocket/labels/flutter_rocket homepage: https://github.com/JahezAcademy/flutter_rocket diff --git a/packages/rocket_mini_view/README.md b/packages/rocket_mini_view/README.md index 01f3e97..f2f6c70 100644 --- a/packages/rocket_mini_view/README.md +++ b/packages/rocket_mini_view/README.md @@ -1,99 +1,82 @@ -# Rocket MiniView +# Rocket MiniView 🚀 -`RocketMiniView` is a widget provided by the `rocket_listenable` package that listens to changes in a `RocketListenable` object and rebuilds when a change occurs. It is designed to be used in conjunction with `RocketValue` objects to build reactive UIs in Flutter. +[![pub package](https://img.shields.io/pub/v/rocket_mini_view.svg)](https://pub.dev/packages/rocket_mini_view) +[![license](https://img.shields.io/github/license/JahezAcademy/mvc_rocket.svg)](LICENSE) -## Usage +A tiny, **reactive** widget that rebuilds automatically when a `RocketListenable` (e.g. `RocketValue`) changes. It lives in the `rocket_listenable` ecosystem and lets you write concise, declarative UI code without boilerplate. -To use `RocketMiniView`, import it into your Dart file: +## 📦 Installation -```dart -import 'package:flutter/material.dart'; -import 'package:rocket_listenable/rocket_listenable.dart'; -import 'package:your_app/constants.dart'; - -import 'rocket_mini_view.dart'; - -final RocketValue value = [].mini; -... -RocketMiniView( - value: value, - builder: () { - return Text(value.length.toString()); - }, -) -``` - -The `RocketMiniView` widget takes two required parameters: - -- `value`: The `RocketListenable` object to listen to. -- `builder`: A function that returns the widget tree to build. +Add the dependency to your `pubspec.yaml`: -The `builder` function should return the widget tree that needs to be rebuilt when the `RocketListenable` object changes. - -## API Reference - -### `RocketMiniView` - -The `RocketMiniView` widget is a widget that listens to changes in a `RocketListenable` object and rebuilds when a change occurs. - -#### Constructor - -```dart -RocketMiniView({ - Key? key, - required this.value, - required this.builder, -}) +```yaml +dependencies: + rocket_mini_view: ^0.0.1 ``` -- `key`: An optional `Key` object to use for the widget. -- `value`: The `RocketListenable` object to listen to. -- `builder`: A function that returns the widget tree to build. +Then fetch the packages: -#### `MiniViewRocketState` - -The `MiniViewRocketState` class is the state object for the `RocketMiniView` widget. - -#### `initState` Method - -```dart -void initState() +```bash +flutter pub get ``` -Called when the widget is first inserted into the widget tree. +## 🎯 Getting Started -#### `didUpdateWidget` Method +Import the widget: ```dart -void didUpdateWidget(RocketMiniView oldWidget) +import 'package:rocket_mini_view/rocket_mini_view.dart'; ``` -Called when the widget is updated with new parameters. - -#### `dispose` Method +### Simple example ```dart -void dispose() +import 'package:flutter/material.dart'; +import 'package:rocket_listenable/rocket_listenable.dart'; +import 'package:rocket_mini_view/rocket_mini_view.dart'; + +final RocketValue> items = RocketValue([]); + +class CounterDemo extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('MiniView Demo')), + body: Center( + child: RocketMiniView( + value: items, + builder: () => Text('Items count: ${items.value.length}'), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () => items.value = [...items.value, 'Item ${items.value.length + 1}'], + child: const Icon(Icons.add), + ), + ); + } +} ``` -Called when the widget is removed from the widget tree. - -#### `_rebuildWidget` Method +The `builder` runs each time `items` changes, giving you an instantly‑updating UI. -```dart -void _rebuildWidget() -``` +## 🛠️ API Overview -Called when the `RocketListenable` object changes. +| Class / Constructor | Description | +|---------------------|-------------| +| `RocketMiniView({Key? key, required RocketListenable value, required Widget Function() builder})` | Core widget that listens to `value` and rebuilds using `builder`. | +| `MiniViewRocketState` | Internal `State` implementation – handles subscription lifecycle (`initState`, `didUpdateWidget`, `dispose`). | +| `_rebuildWidget()` | Private helper called when the listened object notifies listeners. | +| `build(BuildContext context)` | Returns the widget produced by `builder`. | -#### `build` Method +### Parameters +- **`value`** – The `RocketListenable` (e.g. `RocketValue`, `RocketListenable`) you want to observe. +- **`builder`** – A zero‑argument function that returns the widget tree to render. +- **`key`** – Optional widget key. -```dart -Widget build(BuildContext context) -``` +## 🤝 Contributing -Builds the widget tree using the `builder` function. +Feel free to open issues or submit pull requests on the [GitHub repository](https://github.com/JahezAcademy/mvc_rocket). Contributions that add examples, improve documentation, or extend functionality are especially welcome. -## Conclusion +## 📄 License -`RocketMiniView` is a useful widget provided by the `rocket_listenable` package that enables you to build reactive UIs in Flutter. Its simple API and ability to listen to changes in `RocketListenable` objects make it an ideal choice for building Flutter applications that need to react to changes in data. \ No newline at end of file +This package is released under the MIT License – see the [LICENSE](LICENSE) file for details. diff --git a/packages/rocket_model/README.md b/packages/rocket_model/README.md index e63146a..c65bc8e 100644 --- a/packages/rocket_model/README.md +++ b/packages/rocket_model/README.md @@ -1,179 +1,176 @@ -# RocketModel -RocketModel get data from [RocketClient](https://pub.dev/packages/rocket_client) & Show it with [RocketView](https://pub.dev/packages/rocket_view) +# Rocket Model 🚀 -An abstract class that defines the behavior of a model object in Flutter. +[![pub package](https://img.shields.io/pub/v/rocket_model.svg)](https://pub.dev/packages/rocket_model) +[![license](https://img.shields.io/github/license/JahezAcademy/mvc_rocket.svg)](LICENSE) -A model object is a class that represents data and provides methods for managing and updating that data. The data can be stored in various forms (e.g. in-memory, in a database, or on a server) and can be accessed and manipulated through the model object's public methods. +A **type‑safe, reactive model layer** for Flutter/Dart that works hand‑in‑hand with `rocket_client` for data fetching and `rocket_view` for UI rendering. Define your data models once, get automatic JSON (de)serialization, state handling, and listener notifications. -## Features +## 📦 Installation -- Provides a base class for creating model objects in Flutter. -- Allows you to define the behavior of model objects in a consistent and predictable way. -- Implements the `RocketListenable` mixin, which allows you to notify listeners when the model changes. -- Includes methods for managing and updating data, such as adding and deleting items. -- Provides hooks for handling data loading and error handling. +Add the dependency to your `pubspec.yaml`: -## Getting Started - -To use `RocketModel` in your Flutter app, you'll need to import the `rocket_listenable` and `rocket_exception` packages. You can then create a new class that extends `RocketModel` and define the behavior of your model object in that class. - -```dart -import 'package:flutter/foundation.dart'; -import 'package:rocket_listenable/rocket_listenable.dart'; - -import 'constants.dart'; +```yaml +dependencies: + rocket_model: ^0.0.1 +``` -import 'rocket_exception.dart'; +Then run: -abstract class RocketModel extends RocketListenable { - // ... -} +```bash +flutter pub get ``` -Once you've created your `RocketModel` subclass, you can use it to manage and update data in your app. For example, you might use a model object to manage a list of items that you want to display in a view. +## 🎯 Quick Start ```dart -class MyItem { - final String name; - final String description; - - MyItem({required this.name, required this.description}); -} - -class MyModel extends RocketModel { - MyModel() { - // Load data from a server or database... - } - - @override - void fromJson(Map json, {bool isSub = false}) { - // Deserialize data from a JSON map... - } - - @override - Map toJson() { - // Serialize data to a JSON map... - return {}; - } -} - -class MyView extends StatelessWidget { - final MyModel model = MyModel(); - - @override - Widget build(BuildContext context) { - return ListView.builder( - itemCount: model.all?.length ?? 0, - itemBuilder: (BuildContext context, int index) { - final item = model.all![index]; - return ListTile( - title: Text(item.name), - subtitle: Text(item.description), - ); - }, - ); - } -} +import 'package:rocket_model/rocket_model.dart'; +import 'package:rocket_client/rocket_client.dart'; +import 'package:rocket_view/rocket_view.dart'; ``` -## API Documentation - -### RocketModel - -An abstract class that defines the behavior of a model object. +## 🛠️ Rocket CLI -#### Properties +It is **highly recommended** to use [rocket_cli](https://pub.dev/packages/rocket_cli) to generate your models. It automates the creation of boilerplate code, including `fromJson`, `toJson`, and field definitions. -- `instance`: The dynamic instance of the model. -- `_loadingChecker`: A flag indicating whether the model is currently loading data. -- `existData`: A flag indicating whether the model contains any data. -- `exception`: An exception object that represents any errors that occur during data loading or manipulation. -- `all`: A list of all data objects of type `T`. -- `_state`: The current state of the model. +**Installation:** -#### Methods +```bash +dart pub global activate rocket_cli +``` -- `setException(RocketException exception)`: Sets the exception object with the given exception. -- `delItem(int index)`: Deletes the data object at the specified index. -- `addItem(T newModel)`: Adds a new data object. -- `_mapToInstance(e)`: Maps the given data to an instance of the model. -- `setMulti(List data)`: Sets the model's data to the given list of data. -- `fromJson(Map json, {bool isSub = false})`: Deserializes the model's data from the given JSON map. -- `toJson()`: Serializes the model's data to a JSON map. -- `rebuildWidget({bool fromUpdate = false})`: Notifies listeners that the model has changed and needs to be rebuilt. +**Usage Example:** -### RocketState +Generate a model from a JSON string: -An enum that represents the possible states of a `RocketModel` object. +```bash +rocket_cli -j '{"id": 1, "title": "My Post", "body": "Content"}' -n Post +``` -#### Values +Or from a file: -- `loading`: The model is currently loading data. -- `done`: The model has finished loading data and contains valid data. -- `failed`: An error occurred while loading or manipulating data. +```bash +rocket_cli -f post.json -n Post +``` -## Usage +### 1️⃣ Define a model ```dart -import 'package:flutter_rocket/flutter_rocket.dart'; - -const String postUserIdField = "userId"; -const String postIdField = "id"; const String postTitleField = "title"; -const String postBodyField = "body"; class Post extends RocketModel { int? userId; int? id; String? title; String? body; - // disable logs debugging - @override - bool get enableDebug => false; - Post({ - this.userId, - this.id, - this.title, - this.body, - }); + + Post({this.userId, this.id, this.title, this.body}); + + void updateFields({String? titleField}) { + List fields = []; + if (titleField != null) { + title = titleField; + fields.add(postTitleField); + } + rebuildWidget(fromUpdate: true, fields: fields.isEmpty ? null : fields); + } @override void fromJson(Map json, {bool isSub = false}) { - userId = json[postUserIdField]; - id = json[postIdField]; - title = json[postTitleField]; - body = json[postBodyField]; + userId = json['userId']; + id = json['id']; + title = json['title']; + body = json['body']; super.fromJson(json, isSub: isSub); } - void updateFields({ - int? userIdField, - int? idField, - String? titleField, - String? bodyField, - }) { - userId = userIdField ?? userId; - id = idField ?? id; - title = titleField ?? title; - body = bodyField ?? body; - rebuildWidget(fromUpdate: true); - } - @override - Map toJson() { - final Map data = {}; - data[postUserIdField] = userId; - data[postIdField] = id; - data[postTitleField] = title; - data[postBodyField] = body; - - return data; - } + Map toJson() => { + 'userId': userId, + 'id': id, + 'title': title, + 'body': body, + }; @override get instance => Post(); } +``` + +### 2️⃣ Load data with `rocket_client` +Initialize your client and save it to the Rocket singleton: + +```dart +void main() { + final client = RocketClient(url: 'https://jsonplaceholder.typicode.com'); + Rocket.add('posts-api', client); + runApp(MyApp()); +} ``` +### 3️⃣ Show data with `rocket_view` + +```dart +class PostList extends StatelessWidget { + final Post post = Post(); + + @override + Widget build(BuildContext context) { + return RocketView( + model: post, + // call the api using the client key + fetch: () => Rocket.get('posts-api').request('posts', model: post), + builder: (context, state) { + return ListView.builder( + itemCount: post.all!.length, + itemBuilder: (_, i) { + final p = post.all![i]; + return ListTile( + title: Text(p.title ?? ''), + subtitle: Text(p.body ?? ''), + ); + }, + ); + }, + ); + } +} +``` + +The view automatically rebuilds when the model notifies listeners via `rebuildWidget()`. + +## 🛠️ API Overview + +| Class / Member | Description | +|----------------|-------------| +| **`RocketModel`** (abstract) | Base class for all models. Implements `RocketListenable` for reactive updates. | +| `instance` | Factory getter that returns a fresh instance of the concrete model. | +| `all` | List of all loaded items of type `T`. | +| `fromJson(Map json, {bool isSub})` | Populate the model from a JSON map. | +| `toJson()` | Serialize the model back to JSON. | +| `addItem(T item)` | Append a new item to `all` and notify listeners. | +| `delItem(int index)` | Remove an item by index and notify listeners. | +| `setMulti(List data)` | Replace the entire collection with a new list. | +| `setException(RocketException e)` | Store an error that occurred during loading. | +| `rebuildWidget({bool fromUpdate = false})` | Trigger a UI rebuild for listeners. | +| **`RocketState`** (enum) | Loading lifecycle: `loading`, `done`, `failed`. | + +### Key Properties + +- `instance` – concrete model factory. +- `all` – current collection of items. +- `exception` – holds any loading error. +- `state` – current `RocketState`. + +## 🤝 Contributing + +We welcome contributions! Open issues or submit pull requests on the [GitHub repository](https://github.com/JahezAcademy/mvc_rocket). Helpful contributions include: + +- New model examples. +- Improved documentation or tutorials. +- Bug fixes or API extensions. + +## 📄 License + +This package is released under the MIT License – see the [LICENSE](LICENSE) file for details. diff --git a/packages/rocket_singleton/README.md b/packages/rocket_singleton/README.md index 8350c63..b2eaf43 100644 --- a/packages/rocket_singleton/README.md +++ b/packages/rocket_singleton/README.md @@ -1,26 +1,82 @@ +# Rocket Singleton 🚀 -## Getting started +[![pub package](https://img.shields.io/pub/v/rocket_singleton.svg)](https://pub.dev/packages/rocket_singleton) +[![license](https://img.shields.io/github/license/JahezAcademy/mvc_rocket.svg)](LICENSE) -Rocket Singleton easy package for save and get data from memory by type or key +A lightweight, type‑safe singleton utility for Flutter/Dart that lets you **store** and **retrieve** objects in memory by **type** or **custom key**. +It works without any boilerplate, supports read‑only values, and provides convenient extension methods. -## Usage +## 📦 Installation + +Add the dependency to your `pubspec.yaml`: + +```yaml +dependencies: + rocket_singleton: ^0.0.1 +``` + +Then run: + +```bash +flutter pub get +``` + +## 🎯 Getting Started + +Import the package: ```dart -// Use save extension -final Post post = Post().save(key: "post", readOnly: true); -// Or -// Use Rocket object -Rocket.add(value,readOnly: true); // you can't edit it if readonly true -// or -// add by key if you have multi object with same type -Rocket.add(value, key: "key"); -// [get] return value -Rocket.get("key"); -// or get only by Type -Rocket.get() -// [remove] -Rocket.remove("key"); -// remove with condition -Rocket.removeWhere((key,value)=>key.contains("ke")); - -``` \ No newline at end of file +import 'package:rocket_singleton/rocket_singleton.dart'; +``` + +### Saving values + +```dart +// Using the extension on any object +final post = Post() + .save(key: 'post', readOnly: true); // readOnly prevents further edits + +// Directly via the Rocket singleton +Rocket.add(post, readOnly: true); + +// Storing multiple objects of the same type with a custom key +Rocket.add(post, key: 'featuredPost'); +``` + +### Retrieving values + +```dart +// By key (type inference) +final savedPost = Rocket.get('post'); + +// By type only – returns the first matching instance +final anyPost = Rocket.get(); +``` + +### Removing values + +```dart +// Remove a specific entry +Rocket.remove('post'); + +// Remove by condition +Rocket.removeWhere((key, value) => key.startsWith('temp_')); +``` + +## 🛠️ API Overview + +| Method | Description | +|--------|-------------| +| `Rocket.add(T value, {String? key, bool readOnly = false})` | Store a value. If `key` is omitted, the type is used as the identifier. | +| `Rocket.get([String? key])` | Retrieve a value by key or by type. | +| `Rocket.remove(String key)` | Delete a stored entry. | +| `Rocket.removeWhere(bool Function(String key, dynamic value) predicate)` | Delete entries that match a predicate. | +| `T.save({String? key, bool readOnly = false})` *(extension)* | Shortcut to add the object to the singleton. | + +## 🤝 Contributing + +Contributions are welcome! Please open an issue or submit a pull request on the [GitHub repository](https://github.com/JahezAcademy/mvc_rocket). + +## 📄 License + +This project is licensed under the MIT License – see the [LICENSE](LICENSE) file for details.