nano_core 0.1.0 copy "nano_core: ^0.1.0" to clipboard
nano_core: ^0.1.0 copied to clipboard

A lightweight reactive architecture framework and design system toolkit for Flutter multiplatform applications.

Nano Core #

Pub Version License: MIT Status: Stable

A lightweight reactive architecture framework and design system toolkit for Flutter multiplatform applications.

Features #

  • 🚀 NanoScaffold: Reactive base page scaffold supporting Web/Desktop headers, mobile AppBars, loading overlays, and error/warning/success toasts.
  • NanoController & NanoState: Clean, reactive state management built on ChangeNotifier and ListenableBuilder.
  • 📊 NanoViewState: Base class for structured, immutable and equatable view/page state data models.
  • 🛠️ NanoCommand & NanoCommandBuilder: Encapsulated async commands for user actions and operations.
  • 🌐 NanoHttpClient & NanoHttpResponse: Standardized generic contract for decoupled HTTP communication, status codes, and helper extensions (isSuccess, isClientError, isServerError).
  • 📦 NanoRepository & NanoAdapter: Automated generic CRUD repository layer with serialization/deserialization for domain entities.
  • 🏷️ NanoEntity & NanoEquatable: Base domain entity with unique identification and value-based equality.
  • 💉 NanoInjections & NanoStatePage: Dependency injection scoping with GetIt and page lifecycle binding.
  • 🧩 Design System Components: Standalone reusable UI widgets such as NanoLoadingOverlay and NanoToast.
  • 🖥️ NanoDeviceType: Real-time cross-platform environment and responsive viewport width inspection.

Getting Started #

Add nano_core to your pubspec.yaml:

dependencies:
  nano_core: ^0.1.0

Quick Example #

1. Domain Entity & Adapter #

import 'package:nano_core/nano_core.dart';

class User extends NanoEntity<String> {
  final String name;
  const User({required super.id, required this.name});
}

class UserAdapter implements NanoAdapter<User> {
  const UserAdapter();

  @override
  User fromJson(Map<String, dynamic> json) => User(
    id: json['id'] as String,
    name: json['name'] as String,
  );

  @override
  Map<String, dynamic> toJson(User user) => {
    'id': user.id,
    'name': user.name,
  };
}

class UserRepository extends NanoRepository<User, String> {
  UserRepository(NanoHttpClient client)
      : super(
          client: client,
          endpoint: '/users',
          adapter: const UserAdapter(),
        );
}

2. View State, Controller & Injections #

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:nano_core/nano_core.dart';

// 1. Structured View State
class UsersViewState extends NanoViewState {
  final List<User> users;
  const UsersViewState({this.users = const []});

  @override
  List<Object?> get props => [users];
}

// 2. Reactive Controller
class MyController extends NanoController<UsersViewState> {
  final UserRepository repository;

  MyController({required this.repository});

  @override
  Future<void> init(String? id) async {
    await loadUsers();
  }

  Future<void> loadUsers() async {
    execute(() async {
      final users = await repository.getAll();
      return UsersViewState(users: users);
    });
  }
}

// 3. Page Injections Scope
class UsersInjections extends NanoInjections {
  UsersInjections() : super(scope: 'users');

  @override
  void binds(GetIt i) {
    i.registerLazySingleton<UserRepository>(
      () => UserRepository(i<NanoHttpClient>()),
    );
    i.registerFactory<MyController>(
      () => MyController(repository: i<UserRepository>()),
    );
  }
}

// 4. Page with NanoStatePage & NanoScaffold
class UsersPage extends StatefulWidget {
  const UsersPage({super.key});

  @override
  State<UsersPage> createState() => _UsersPageState();
}

class _UsersPageState
    extends NanoStatePage<UsersPage, MyController> {
  @override
  NanoInjections get injections => UsersInjections();

  @override
  Widget build(BuildContext context) {
    return NanoScaffold<UsersViewState, NanoMessageKey>(
      controller: controller,
      headerBuilder: (context, state) => AppBar(
        title: Text(
          state.data?.users.isNotEmpty == true
              ? 'Users (${state.data!.users.length})'
              : 'Users List',
        ),
      ),
      builder: (context, state) {
        final users = state.data?.users ?? [];
        return ListView.builder(
          itemCount: users.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(users[index].name),
            );
          },
        );
      },
    );
  }
}

3. HTTP Client Implementation with Dio (Optional) #

nano_core remains 100% agnostic to third-party HTTP dependencies. To use Dio as your HTTP client, implement NanoHttpClient in your app:

import 'package:dio/dio.dart';
import 'package:nano_core/nano_core.dart';

class DioHttpClient implements NanoHttpClient {
  final Dio _dio;

  DioHttpClient(this._dio);

  @override
  Future<NanoHttpResponse<T>> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
  }) async {
    final response = await _dio.get<T>(
      path,
      queryParameters: queryParameters,
      options: Options(headers: headers),
    );
    return NanoHttpResponse<T>(
      data: response.data,
      statusCode: response.statusCode,
      statusMessage: response.statusMessage,
    );
  }

  @override
  Future<NanoHttpResponse<T>> post<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
  }) async {
    final response = await _dio.post<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: Options(headers: headers),
    );
    return NanoHttpResponse<T>(
      data: response.data,
      statusCode: response.statusCode,
      statusMessage: response.statusMessage,
    );
  }

  @override
  Future<NanoHttpResponse<T>> put<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
  }) async {
    final response = await _dio.put<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: Options(headers: headers),
    );
    return NanoHttpResponse<T>(
      data: response.data,
      statusCode: response.statusCode,
      statusMessage: response.statusMessage,
    );
  }

  @override
  Future<NanoHttpResponse<T>> delete<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
  }) async {
    final response = await _dio.delete<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: Options(headers: headers),
    );
    return NanoHttpResponse<T>(
      data: response.data,
      statusCode: response.statusCode,
      statusMessage: response.statusMessage,
    );
  }

  @override
  Future<NanoHttpResponse<T>> patch<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Map<String, String>? headers,
  }) async {
    final response = await _dio.patch<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: Options(headers: headers),
    );
    return NanoHttpResponse<T>(
      data: response.data,
      statusCode: response.statusCode,
      statusMessage: response.statusMessage,
    );
  }
}

Register it once at app startup with GetIt / NanoInjections:

void main() {
  final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
  GetIt.I.registerLazySingleton<NanoHttpClient>(() => DioHttpClient(dio));
  runApp(const MyApp());
}

License #

This project is licensed under the MIT License - see the LICENSE file for details.

5
likes
0
points
1.22k
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight reactive architecture framework and design system toolkit for Flutter multiplatform applications.

Homepage
Repository (GitHub)
View/report issues

Topics

#architecture #state-management #design-system #routing #scaffold

License

unknown (license)

Dependencies

cupertino_icons, flutter, get_it

More

Packages that depend on nano_core