yasml 0.3.2 copy "yasml: ^0.3.2" to clipboard
yasml: ^0.3.2 copied to clipboard

Yet Another State Management Library — explicit, traceable, compiler-verified state management for Flutter.

example/example.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:yasml/yasml.dart';

// --- Model ---

class Todo {
  const Todo({required this.id, required this.title, required this.completed});

  factory Todo.fromJson(Map<String, dynamic> json) => Todo(
    id: json['id'] as int,
    title: json['title'] as String,
    completed: json['completed'] as bool,
  );

  final int id;
  final String title;
  final bool completed;
}

// --- Data layer ---

final Dio dio = Dio(BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com'));

// 1. Query — fetches the todo list from the API
final FutureQuery<List<Todo>> todosQuery = FutureQuery.create(
  (world) async {
    final response = await dio.get<List<dynamic>>('/todos?_limit=10');
    return response.data!.map((dynamic e) => Todo.fromJson(e as Map<String, dynamic>)).toList();
  },
  key: 'TodosQuery',
);

// 2. Command — toggles a todo's completion and invalidates the query
Command<void> toggleTodo(Todo todo) => Command.create(
  (world) async {
    await dio.patch<void>('/todos/${todo.id}', data: {'completed': !todo.completed});
  },
  (_) => [todosQuery],
);

// 3. Composition — watches the query and projects it into view-model state
final AsyncComposition<List<Todo>> todosComposition = AsyncComposition.create(
  (composer) => composer.watchFuture(todosQuery),
  key: 'TodosComposition',
);

// 4. Mutation — the only API the UI touches
base class TodosMutation extends Mutation<AsyncComposition<List<Todo>>> {
  const TodosMutation({required super.commander});

  Future<void> toggle(Todo todo) => commander.dispatch(toggleTodo(todo));
}

// 5. View — binds composition + mutation to a widget
base class TodosView extends ViewWidget<AsyncValue<List<Todo>>, AsyncComposition<List<Todo>>, TodosMutation> {
  const TodosView({required super.world, super.key});

  @override
  AsyncComposition<List<Todo>> get composition => todosComposition;

  @override
  MutationConstructor<TodosMutation> get mutationConstructor => (commander) => TodosMutation(commander: commander);

  @override
  Widget build(BuildContext context, AsyncValue<List<Todo>> state, Notifier<TodosMutation> notifier) {
    return switch (state) {
      AsyncLoading() => const Center(child: CircularProgressIndicator()),
      AsyncError(:final error) => Center(child: Text('Error: $error')),
      AsyncData(:final data) => ListView.builder(
        itemCount: data.length,
        itemBuilder: (context, index) {
          final todo = data[index];
          return CheckboxListTile(
            value: todo.completed,
            title: Text(todo.title),
            onChanged: (_) => notifier.runMutation((m) => m.toggle(todo)),
          );
        },
      ),
    };
  }
}

// Bootstrap
void main() {
  final world = World.create(plugins: [], observers: []);
  runApp(MaterialApp(home: Scaffold(body: TodosView(world: world))));
}
1
likes
160
points
106
downloads

Documentation

API reference

Publisher

verified publisherkokodobu.org

Weekly Downloads

Yet Another State Management Library — explicit, traceable, compiler-verified state management for Flutter.

Repository (GitHub)
View/report issues
Contributing

Topics

#state-management #flutter #reactive

License

LGPL-2.1 (license)

Dependencies

async, collection, flutter, logging

More

Packages that depend on yasml