{"id":15008394,"url":"https://github.com/kocherovets/isolated_bloc","last_synced_at":"2026-03-27T04:46:43.763Z","repository":{"id":240645389,"uuid":"803200200","full_name":"kocherovets/isolated_bloc","owner":"kocherovets","description":"Support for running original blocs in an isolate.","archived":false,"fork":false,"pushed_at":"2024-05-22T01:15:50.000Z","size":18080,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-22T10:42:55.295Z","etag":null,"topics":["bloc","concurrency","dart","dart-library","dartlang","flutter","flutter-package","isolate","library","state-management"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kocherovets.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-20T09:10:03.000Z","updated_at":"2024-05-22T01:17:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"89779b43-90db-4267-a088-e9be193af402","html_url":"https://github.com/kocherovets/isolated_bloc","commit_stats":null,"previous_names":["kocherovets/isolated_bloc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kocherovets%2Fisolated_bloc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kocherovets%2Fisolated_bloc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kocherovets%2Fisolated_bloc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kocherovets%2Fisolated_bloc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kocherovets","download_url":"https://codeload.github.com/kocherovets/isolated_bloc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243190870,"owners_count":20250969,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bloc","concurrency","dart","dart-library","dartlang","flutter","flutter-package","isolate","library","state-management"],"created_at":"2024-09-24T19:18:18.143Z","updated_at":"2026-03-27T04:46:43.703Z","avatar_url":"https://github.com/kocherovets.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# isolated_bloc\n\n[![Pub Package](https://img.shields.io/pub/v/isolated_bloc.svg?style=for-the-badge\u0026logo=Dart)](https://pub.dev/packages/isolated_bloc)\n[![Static Badge](https://img.shields.io/badge/dart-blue?style=for-the-badge\u0026logo=dart)](https://dart.dev)\n[![GitHub Issues](https://img.shields.io/github/issues/kocherovets/isolated_bloc.svg?style=for-the-badge\u0026logo=GitHub)](https://github.com/kocherovets/isolated_bloc/issues)\n[![GitHub Stars](https://img.shields.io/github/stars/kocherovets/isolated_bloc.svg?style=for-the-badge\u0026logo=GitHub)](https://github.com/kocherovets/isolated_bloc/stargazers)\n[![GitHub License](https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge\u0026logo=GitHub)](https://raw.githubusercontent.com/kocherovets/isolated_bloc/main/LICENSE)\n\n- [Motivation](#Motivation)\n- [Limitations](#Limitations)\n- [Usage](#Usage)\n  * [Pubspec](#Pubspec)\n  * [Transformation of an existing bloc](#Transformation-of-an-existing-bloc)\n  * [DI](#DI)\n  * [Working with multiple isolates](#Working-with-multiple-isolates)\n- [Demo](#Demo)\n\n## Motivation:\n\nThe library implements the idea of moving business logic to a separate isolate. It works on top of the well-known Bloc library, without changing it, but complementing it.\n\nThe main idea of building an application using this library is to create business logic only with blocs and run all of them in a separate isolate. In this same isolate, it is assumed that most data providers, such as APIs and databases, will be created. This will significantly offload the main isolate for a responsive UI.\n\nHowever, the library does not require you to do so, as it works simply as a wrapper around existing blocs. Therefore, only some of the blocs can be moved to the isolate. Inconveniences may arise in designing interactions with data sources, which will need to be maintained in both the main isolate and the bloc isolate.\n\nMoreover, the library allows blocs to work in different isolates. Each bloc can be assigned an isolate in which it will be created.\n\n## Limitations:\n\n1. The library does not support working with cubits. It works only with blocs.\n2. Due to the actual creation of blocs in an isolate different from the main one, in general, DI through constructor parameters for complex dependencies will cease to work. DI not based on context will need to be set up in the isolate where the blocs operate.\n\n## Usage\n\n### Pubspec\n\n```yaml\ndependencies:\n  isolated_bloc: ^1.3.0\n```\n\n### Transformation of an existing bloc\n\nIn an existing application, to convert a bloc into a bloc running in an isolate, you only need to add three lines and change the class name of the existing bloc.\n\nfrom\n\n```dart\n\nclass CounterBloc extends Bloc\u003cCounterBlocEvent, CounterBlocState\u003e {\n    ...\n}\n```\n\nto\n\n```dart\nimport 'package:isolated_bloc/isolated_bloc.dart';\n\nclass CounterBloc extends IsolatedBloc\u003cCounterBlocEvent, CounterBlocState\u003e {\n  CounterBloc() : super(() =\u003e _CounterBloc());\n}\n\nclass _CounterBloc extends Bloc\u003cCounterBlocEvent, CounterBlocState\u003e {\n    ...\n}\n```\n\nSince the use of isolates is not supported on the web, a simple empty wrapper around the bloc is used for the web, which does nothing by itself.\n\n### DI\n\nTo simplify the transfer of DI into the isolate, a special message is provided in the library. Below is an example of one of the ways to configure GetIt.\n\n```dart\n\nfinal DI = GetIt.instance;\nfinal IsolatedDI = GetIt.instance;\n\n...\n\nclass SetupDIMessageToIsolate extends CallableMessageToIsolate {\n  void call() {\n    final dio = Dio();\n    IsolatedDI.registerSingleton(dio);\n\n    final api = ApiClient(dio);\n    IsolatedDI.registerSingleton(api);\n  }\n}\n\n...\n\nif (kIsWeb) {\n  final dio = Dio();\n  DI.registerSingleton(dio);\n\n  final api = ApiClient(dio);\n  DI.registerSingleton(api);\n\n} else {\n  IsolatedBloc.isolatesDispatcher.isolate().sendMessage(SetupDIMessageToIsolate());\n}\n\n...\n\nclass OriginalRelativesBloc extends Bloc\u003cRelativesBlocEvent, RelativesBlocState\u003e {\n  late final _api = kIsWeb ? DI\u003cApiClient\u003e() : IsolatedDI\u003cApiClient\u003e();\n    ...\n}\n```\n\n### Working with multiple isolates\n\nBy default, all blocks operate in a single isolate. This setup does not require any additional configuration.\n\nHowever, each block can be assigned an isolate in which it will operate. Isolates in the library are distinguished by names. The default isolate name is `IsolatesDispatcher.kDefaultIsolateName`. To create a new isolate, you can simply specify its name when creating a block.\n\n```dart\nclass CounterBloc extends IsolatedBloc\u003cCounterBlocEvent, CounterBlocState\u003e {\n  CounterBloc({required String isolateName})\n      : super(() =\u003e _CounterBloc(), isolateName: isolateName);\n}\n\n...\n\nBlocProvider(create: (BuildContext context) =\u003e CounterBloc(isolateName: _isolateName)),\n```\n\nAlternatively, you can explicitly obtain the isolate, for example, to configure DI (Dependency Injection) within it:\n\n```dart\nIsolatedBloc.isolatesDispatcher.isolate(isolateName: _isolateName);\n```\n\nIf an isolate with this name does not yet exist, it will be created. \n\nWhen the isolate is no longer needed, it can be removed:\n\n```dart\nIsolatedBloc.isolatesDispatcher.removeIsolate(isolateName: _isolateName);\n```\nIf the isolate name is not specified in any of these cases, the default isolate will be used. This default isolate cannot be removed.\n\n## Demo\n\nThe example demonstrates the difference in the application's performance with the original (web) bloc and the bloc in the isolate. The example significantly and prolongedly loads the CPU, which very rarely happens in real applications, but it allows you to clearly see the decoupling of the UI performance from the business logic operations.\n\nhttps://github.com/kocherovets/isolated_bloc/assets/4235844/e5064e84-a02f-45c2-8ef9-a2730f73a1da\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkocherovets%2Fisolated_bloc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkocherovets%2Fisolated_bloc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkocherovets%2Fisolated_bloc/lists"}