ark_data_layer 0.1.0-dev.1 copy "ark_data_layer: ^0.1.0-dev.1" to clipboard
ark_data_layer: ^0.1.0-dev.1 copied to clipboard

Pure Dart foundations for repositories, data sources, and observable business data.

example/ark_data_layer_example.dart

import 'dart:async';

import 'package:ark_data_layer/ark_data_layer.dart';

Future<void> main() async {
  final InMemoryUserDataSource source = InMemoryUserDataSource(<UserDto>[
    const UserDto(id: 'ada', displayName: 'Ada'),
    const UserDto(id: 'linus', displayName: 'Linus'),
  ]);
  final UserRepositoryImpl repository = UserRepositoryImpl(
    dataSources: DataSourceContainer(<DataSource>[source]),
  );
  final List<UsersData> observed = <UsersData>[];
  final StreamSubscription<UsersData> subscription = repository.stream.listen(
    observed.add,
  );

  await repository.refresh();
  await Future<void>.delayed(Duration.zero);

  if (observed.length != 2 || observed.last.users.length != 2) {
    throw StateError('Expected initial and refreshed repository data.');
  }

  await subscription.cancel();
  await repository.close();

  if (source.isClosed) {
    throw StateError('Repository must not close a scope-owned DataSource.');
  }
  await source.close();
}

abstract interface class UserRepository {
  UsersData get data;

  Stream<UsersData> get stream;

  Future<void> refresh();
}

abstract interface class UserRemoteDataSource implements DataSource {
  Future<List<UserDto>> fetchUsers();

  Future<void> close();
}

final class UserRepositoryImpl extends Repository<UsersData>
    implements UserRepository {
  UserRepositoryImpl({required super.dataSources})
    : _remote = dataSources.get<UserRemoteDataSource>(),
      super(initialData: const UsersData.empty());

  final UserRemoteDataSource _remote;

  @override
  Future<void> refresh() async {
    final List<UserDto> records = await _remote.fetchUsers();
    setData(
      UsersData(<User>[
        for (final UserDto record in records)
          User(id: record.id, displayName: record.displayName),
      ]),
    );
  }
}

final class InMemoryUserDataSource implements UserRemoteDataSource {
  InMemoryUserDataSource(final Iterable<UserDto> records)
    : _records = List<UserDto>.unmodifiable(records);

  final List<UserDto> _records;

  bool isClosed = false;

  @override
  Future<List<UserDto>> fetchUsers() async {
    if (isClosed) {
      throw StateError('DataSource is closed.');
    }
    return _records;
  }

  @override
  Future<void> close() async {
    isClosed = true;
  }
}

final class UserDto {
  const UserDto({required this.id, required this.displayName});

  final String id;

  final String displayName;
}

final class User {
  const User({required this.id, required this.displayName});

  final String id;

  final String displayName;
}

final class UsersData {
  const UsersData.empty() : users = const <User>[];

  UsersData(final Iterable<User> users)
    : users = List<User>.unmodifiable(users);

  final List<User> users;
}
0
likes
160
points
23
downloads

Documentation

Documentation
API reference

Publisher

verified publisherarktelos.dev

Weekly Downloads

Pure Dart foundations for repositories, data sources, and observable business data.

Homepage
Repository (GitLab)
View/report issues

Topics

#architecture #data-layer #repository

License

Apache-2.0 (license)

Dependencies

meta

More

Packages that depend on ark_data_layer