Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
459 changes: 137 additions & 322 deletions README.md

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions docs/wiki/Automatic-Bubbling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Automatic Bubbling

**Automatic Bubbling** is a built-in orchestration feature in Flutter Rocket that eliminates the need for manual listener management when working with nested models or collections. It ensures that changes in a child model are automatically "bubbled up" to the parent, triggering a rebuild in any widget listening to the parent.

## The Problem

In most state management systems, if you have a list of items (e.g., `Posts`) and you update a property of a single item (e.g., `Post.title`), the list widget itself won't know it needs to rebuild unless you manually notify it or use complex nested listeners.

## The Solution

In Flutter Rocket, every `RocketModel` is "bubbling-aware." When a model is part of a collection (the `all` list), any call to `rebuildWidget()` on the child model automatically triggers a notification to the parent collection.

## How it Works

Imagine you have a `Posts` model that contains a list of single `Post` items.

1. **The UI**: You have a `RocketView` listening to the `Posts` model.
2. **The Action**: You change the title of `post[5]` using `currentPost.updateFields(...)`.
3. **The Bubbling**:
- `currentPost` calls its listeners (if any selective rebuild fields match).
- `currentPost` then notifies its parent (`Posts`).
- The `RocketView` listening to `Posts` receives the notification and rebuilds.

## Benefits

- **Zero Extra Code**: You don't need to add special "notifyParent" logic.
- **Consistent UI**: Your list views, counters, or summary widgets stay in sync with the individual items they contain.
- **Simplified Architecture**: You can treat your data tree as a single source of truth without worrying about wiring up listeners at every level.

## Example

```dart
// Parent View
RocketView(
model: postModel, // This is a list of posts
builder: (context, state) {
return ListView.builder(
itemCount: postModel.all!.length,
itemBuilder: (context, index) {
final post = postModel.all![index];
return ListTile(
title: Text(post.title!),
onTap: () {
// Updating the CHILD automatically triggers a rebuild of this PARENT list
post.updateFields(titleField: 'Updated Title!');
},
);
},
);
},
)
```

## Performance Note
While bubbling is convenient, it triggers a rebuild of the parent widget. For extreme performance in large lists, combine Bubbling with [**Selective Rebuilds**](Selective-Rebuilds) by wrapping list items in their own `RocketView` to localize updates.
33 changes: 33 additions & 0 deletions docs/wiki/Home.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Welcome to the Flutter Rocket Wiki

**Flutter Rocket** is a high-performance, lightweight state management and API integration solution for Flutter. It is designed to be simple, fast, and feature-rich, providing everything you need to build scalable applications.

## 🚀 Navigation

### Core Concepts
- [**RocketModel**](RocketModel): The heart of your state. Learn how to define data and manage its logic.
- [**RocketClient**](RocketClient): Powerful HTTP requests, interceptors, and caching.
- [**RocketView**](RocketView): The bridge between your data and the UI.

### Performance & Optimization
- [**Selective Rebuilds**](Selective-Rebuilds): High-performance UI updates by rebuilding only what changed.
- [**Automatic Bubbling**](Automatic-Bubbling): How nested models notify their parents automatically.

### Tools
- [**Rocket CLI**](RocketCLI): Generate optimized models instantly from JSON.

---

## Why Flutter Rocket?

1. **Lightweight**: Zero external dependencies (other than core libraries).
2. **Performance First**: Optimized for minimum rebuilds and memory usage.
3. **Productivity**: Built-in tools and patterns to reduce boilerplate.
4. **Flexible**: Use as much or as little as you need.

## Community & Support
- **General Support**: [GitHub Discussions](https://github.com/JahezAcademy/flutter_rocket/discussions)
- **Reporting Bugs**: [GitHub Issues](https://github.com/JahezAcademy/flutter_rocket/issues)
- **Examples**: [Example Project](https://github.com/JahezAcademy/flutter_rocket/tree/main/example)

Built with ❤️ by the [Jahez Team](https://github.com/JahezAcademy).
46 changes: 46 additions & 0 deletions docs/wiki/RocketCLI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Rocket CLI

`rocket_cli` is a command-line tool designed to eliminate the boilerplate of creating `RocketModel` classes. It converts any JSON (from a string or a file) into fully optimized Dart code.

## Installation

Activate the CLI globally using Dart:

```bash
dart pub global activate rocket_cli
```

## Usage

You can generate a model from a JSON string:

```bash
rocket_cli -j '{"id": 1, "name": "John"}' -n User
```

Or from a JSON file:

```bash
rocket_cli -f data.json -n Result
```

## Features

- **Automatic Serialization**: Generates `fromJson` and `toJson` methods.
- **Field Constants**: Automatically creates `const` strings for field keys to prevent typos.
- **Performance Optimized**: Generates `updateFields` logic with built-in support for **Selective Rebuilds**.
- **Nested Detection**: Automatically detects nested objects and lists, generating appropriate sub-models.
- **DateTime Support**: Automatically detects and handles ISO8601 date strings.

## Generated Model Structure

When you run the tool, it creates a Dart file containing:
1. **Constants**: `const String userIdField = "id";`
2. **Model Class**: `class User extends RocketModel<User> { ... }`
3. **Methods**:
* `fromJson`: To parse API data.
* `toJson`: To send data back.
* `updateFields`: Optimized for high-performance state updates.

## Why use it?
Manually writing model serialization is error-prone and tedious. `rocket_cli` ensures your models are consistent, follow best practices, and are optimized for the latest features of Flutter Rocket.
81 changes: 81 additions & 0 deletions docs/wiki/RocketClient.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# RocketClient

`RocketClient` is a powerful HTTP client built into Flutter Rocket. It handles requests, responses, state transitions in models, and includes features like interceptors and caching.

## Basic Usage

Initialize the client with a base URL:

```dart
final client = RocketClient(url: 'https://api.example.com');
```

## Making Requests

Use the `request` method to fetch data. It automatically handles the `RocketModel` state.

```dart
await client.request(
'posts',
model: postModel,
method: RocketMethods.get, // Default is GET
);
```

### Request Parameters
- `model`: The `RocketModel` that will store the response.
- `params`: Query parameters.
- `data`: Request body (for POST/PUT).
- `target`: If the data you want is nested in the JSON response (e.g., `['data', 'items']`).

## Interceptors

Interceptors allow you to run code before a request is sent or after a response is received.

```dart
final client = Rocketクライアント(
url: 'https://api.example.com',
beforeRequest: (request) {
// Add Auth token
request.headers['Authorization'] = 'Bearer your_token';
return request;
},
afterResponse: (response) {
// Log status or refresh token
print('Status: ${response.statusCode}');
return response;
},
);
```

## Caching

Speed up your app by caching network responses.

1. **Initialize Caching**:
```dart
void main() async {
await RocketCache.init();
runApp(MyApp());
}
```

2. **Use in Request**:
```dart
client.request(
'posts',
model: postModel,
cacheKey: 'posts_cache',
cacheDuration: Duration(hours: 1),
);
```

## Multi-Part Requests (Files)

```dart
client.sendFile(
'upload',
fields: {'name': 'profile'},
files: {'avatar': 'path/to/image.png'},
);
```
79 changes: 79 additions & 0 deletions docs/wiki/RocketModel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# RocketModel

`RocketModel` is the base class for all your data models. It provides built-in state management, JSON serialization, and notification logic.

## Defining a Model

A `RocketModel` typically consists of:
1. **Properties**: Your data fields.
2. **Field Constants**: String keys matched to JSON keys.
3. **fromJson**: Logic to populate fields from a Map.
4. **updateFields**: Logic to update specific fields and trigger selective rebuilds.

### Example Model

```dart
import 'package:flutter_rocket/flutter_rocket.dart';

// 1. Define field keys as constants for reliability
const String userIdField = "userId";
const String idField = "id";
const String titleField = "title";

class Post extends RocketModel<Post> {
// 2. Properties
int? userId;
int? id;
String? title;

Post({this.userId, this.id, this.title});

// 3. Populate from JSON
@override
void fromJson(Map<String, dynamic>? json, {bool isSub = false}) {
if (json == null) return;
userId = json[userIdField];
id = json[idField];
title = json[titleField];
super.fromJson(json, isSub: isSub);
}

// 4. Update fields and trigger selective rebuilds
void updateFields({int? userIdField, int? idField, String? titleField}) {
List<String> fields = [];
if (userIdField != null) {
userId = userIdField;
fields.add(userIdField);
}
// ... add logic for other fields
rebuildWidget(fromUpdate: true, fields: fields.isEmpty ? null : fields);
}

@override
Post get instance => Post();
}
```

## State Management

Every `RocketModel` has a `state` property of type `RocketState`:
- `RocketState.loading`: Data is being fetched.
- `RocketState.done`: Data is loaded successfully.
- `RocketState.failed`: An error occurred.

You can check the state in your UI to show loaders or error messages.

## Data Collections

When you fetch a list of items, the `all` property of the `RocketModel` holds the list. It is also an instance of `RocketModel` (or a subclass) that manages the list state.

```dart
final Post posts = Post();
// After fetching...
print(posts.all!.length);
```

## Tips
- Use **Rocket CLI** to generate these models instantly.
- Always use constant strings for field names to avoid typos.
- Override `enableDebug` to `true` during development to see state transition logs.
55 changes: 55 additions & 0 deletions docs/wiki/RocketView.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# RocketView

`RocketView` is the primary widget used to bind your `RocketModel` to the UI. It automatically reacts to state changes (loading, done, failed) and rebuilds when data changes.

## Basic Usage

```dart
RocketView(
model: postModel,
fetch: () => client.request('posts', model: postModel),
builder: (context, state) {
return ListView.builder(
itemCount: postModel.all!.length,
itemBuilder: (context, index) => Text(postModel.all![index].title!),
);
},
)
```

## Parameters

- `model`: The `RocketModel` instance to listen to.
- `fetch`: A function that makes the API call. Runs automatically based on `callType`.
- `builder`: The UI builder. Receives the current `RocketState`.
- `loader`: (Optional) Custom widget to show during `loading`.
- `onError`: (Optional) Custom widget to show on `failed`. Receives the exception and a reload function.
- `callType`: Determines when `fetch` is called:
- `CallType.callIfModelEmpty`: Only fetch if `model.all` is empty.
- `CallType.callAsStream`: Repeatedly fetch data every `secondsOfStream`.
- `CallType.callAsFuture`: Always fetch when the widget is initialized.

## Performance Optimization

Use the `fields` parameter to implement **Selective Rebuilds**. This tells `RocketView` to only rebuild if specific properties of the model change.

```dart
RocketView(
model: currentPost,
fields: [postTitleField], // Only rebuilds if the 'title' property changes
builder: (context, state) => Text(currentPost.title!),
)
```

## Mini Views

For simple local state (like a counter or a toggling boolean), use `RocketMiniView` with `RocketValue`.

```dart
final count = 0.mini;

RocketMiniView(
value: count,
builder: () => Text('Count: ${count.v}'),
)
```
Loading