streambox_core 1.0.0 copy "streambox_core: ^1.0.0" to clipboard
streambox_core: ^1.0.0 copied to clipboard

Core for stream-based caching and data strategy architecture.

streambox logo

streambox_core #

A lightweight and extensible caching and repository framework for Dart & Flutter.
streambox_core helps you manage data fetching, caching, and reactive streams
with clean abstractions and powerful strategies.

Build Status pub package codecov style: very good analysis Verified Publisher


✨ Features #

  • Repository Pattern out of the box
  • Built-in cache strategies:
    • Cache First
    • Cache Then Refresh
    • No-Op (no caching)
  • Composable data sources:
    • Single source
    • Chained sources
    • Periodic fetch
    • External stream integration
  • Reactive state management via Stream<DataState<T>>
  • Strongly typed request payloads: initial, loading, success, error
  • Behavior & Broadcast stream adapters
  • Easy to extend and integrate with your networking or persistence layer

πŸ“¦ Installation #

Add to your pubspec.yaml:

dependencies:
  streambox_core: ^1.0.0

🧩 Core Concepts #

DataState #

Represents the state of data flow:

  • DataInitial β€” no data yet
  • DataLoading β€” loading in progress
  • DataSuccess β€” data successfully loaded
  • DataError β€” an error occurred

Cache Strategies #

  • CacheFirstStrategy β€” returns cached data if available; fetches otherwise.
  • CacheThenRefreshStrategy β€” returns cached data immediately and refreshes with a new fetch.
  • NoOpCacheStrategy β€” always fetches fresh data without caching.

Repositories #

  • SingleSourceRepo β€” wraps a single data source
  • ChainedSourcesRepo β€” combines two dependent data sources
  • PeriodicRepo β€” refetches data at a given interval
  • BaseRepo β€” provides loading/error/flush helpers

Repositories optionally support:

  • initialFetchParams to perform an immediate request with parameters
  • fetchOnInit to trigger the first request on creation
  • replayLast to replay the last emitted state to new subscribers

πŸ—„οΈ Storage Adapters #

streambox_core provides several ready-to-use implementations of KeyValueStoreInterface, allowing you to plug in different storage backends depending on your requirements.

MemoryStoreAdapter #

  • Description: Stores values in memory only.
  • Use cases: Testing, prototyping, ephemeral caches.
  • Persistence: ❌ (cleared when app restarts).

AsyncSharedPrefsStorageAdapter #

  • Description: Uses the asynchronous SharedPreferencesAsync API.
  • Use cases: General persistent storage where async access is acceptable.
  • Persistence: βœ… (backed by shared preferences).

CachedPrefsAdapter #

  • Description: Backed by SharedPreferencesWithCache, minimizing disk I/O with an in-memory cache.
  • Use cases: Persistent storage with improved performance by caching reads.
  • Persistence: βœ… (cached + disk-backed).

FlutterSecureStorageAdapter #

  • Description: Backed by flutter_secure_storage for encrypted key-value storage.
  • Use cases: Securely storing sensitive data such as tokens, credentials, or secrets.
  • Persistence: βœ… (secure and encrypted).

πŸ“˜ Example Setup #

Below is an abstract example showing how to wire together a data source, a cache strategy, and a repository. Each component belongs to a specific application layer.

// πŸ“‚ data layer
@RestApi()
abstract interface class ExampleApiInterface {
  factory ExampleApiInterface(Dio dio) = _ExampleApiInterface;

  @GET('items')
  Future<ItemResponse> fetchItems({
    @Query('page') required int page,
    @Query('size') required int size,
  });
}

final class ExampleDataSource
    extends BaseDataSource<FetchParams, ItemResponse> {
  ExampleDataSource({
    required ExampleApiInterface api,
    required super.cacheStrategy,
  }) : _api = api;

  final ExampleApiInterface _api;

  @override
  Future<ItemResponse> request(FetchParams? params) {
    assert(params != null);
    return _api.fetchItems(page: params!.page, size: params.size);
  }
}

final class ExampleCacheStrategy
    extends CacheThenRefreshStrategy<FetchParams, ItemResponse> {
  ExampleCacheStrategy({required super.cache});

  @override
  String resolveKey(FetchParams? params) => '${params?.page}-${params?.size}';
}

final class ExampleCache extends BaseKeyValueCache<ItemResponse> {
  const ExampleCache({required super.store});

  @override
  String get keyPrefix => 'items';

  @override
  ItemResponse deserialize(String source) =>
      ItemResponse.fromJson(decodeAsMap(source));

  @override
  String serialize(ItemResponse value) => encode(value.toJson());
}

final class ExampleRepoImpl
    extends SingleSourceRepo<FetchParams, ItemResponse, ExampleEntity>
    implements ExampleRepo {
  ExampleRepoImpl({required super.dataSource});

  @override
  ExampleEntity map(FetchParams? params, ItemResponse value) =>
      ExampleMapper(value).toEntity();
}

// πŸ“‚ domain layer
abstract interface class ExampleRepo
    implements Repo<FetchParams, ExampleEntity> {}

// πŸ“‚ di module
final exampleRepo = ExampleRepoImpl(
  dataSource: ExampleDataSource(
    api: ExampleApiInterface(dio),
    cacheStrategy: ExampleCacheStrategy(
      cache: ExampleCache(store: MemoryStoreAdapter()),
    ),
  ),
);

If you don't need caching, simply replace the cache strategy with:

cacheStrategy: NoOpCacheStrategy(),

πŸ›  Extensibility #

You can implement:

  • Custom Cache backends
  • Your own CacheStrategy
  • Specialized DataSource integrations
  • Custom storage adapters

1
likes
0
points
194
downloads

Publisher

verified publisherkalaganov.dev

Weekly Downloads

Core for stream-based caching and data strategy architecture.

Repository (GitHub)
View/report issues

Topics

#repository #caching #reactive #strategy #core

License

unknown (license)

Dependencies

flutter_secure_storage, meta, shared_preferences

More

Packages that depend on streambox_core