syncache_hive
Hive storage backend for Syncache - cross-platform persistent caching.
Features
- Persistent storage using Hive
- Cross-platform support (iOS, Android, Web, Desktop, Pure Dart)
- Full support for tag-based cache invalidation
- Pattern-based key matching and deletion
- Automatic serialization via JSON
- Atomic operations - each entry (data + tags) is stored as a single unit
- Index-backed tag operations - tag lookups use an in-memory secondary
index (rebuilt lazily with a single key-only scan after open), so
getKeysByTag/deleteByTagare O(matches), never a full box scan that deserializes every value
Installation
Add syncache_hive to your pubspec.yaml:
dependencies:
syncache: ^0.6.0
syncache_hive: ^0.6.0
hive_ce: ^2.20.2
For Flutter apps, also add hive_ce_flutter:
dependencies:
hive_ce_flutter: ^2.4.0
Backend dependency stance
syncache_hive depends on hive_ce —
the community edition of Hive — not the discontinued hive package.
The constraint is an honest caret (^2.20.2): any hive_ce release within
major version 2 works. hive_ce ships independent major bumps, so this
package only follows a major bump deliberately (with migration testing of
on-disk format compatibility), not automatically. Treat hive_ce major
upgrades as their own small change to this package, and pin your own app to
a caret range you have tested.
Usage
Basic Setup
import 'package:hive_ce/hive_ce.dart';
import 'package:syncache/syncache.dart';
import 'package:syncache_hive/syncache_hive.dart';
class User {
final int id;
final String name;
const User({required this.id, required this.name});
Map<String, dynamic> toJson() => {'id': id, 'name': name};
static User fromJson(Map<String, dynamic> json) =>
User(id: json['id'] as int, name: json['name'] as String);
}
final api = Api();
class Api {
Future<User> getUser(String id) async => User(id: 123, name: 'User');
}
Future<void> main() async {
// Initialize Hive (required once per app)
Hive.init('path/to/hive');
// Open a HiveStore with your data type
final store = await HiveStore.open<User>(
boxName: 'users',
fromJson: User.fromJson,
toJson: (user) => user.toJson(),
);
// Create a Syncache instance with the store
final cache = Syncache<User>(store: store);
// Use the cache
final user = await cache.get(
key: 'user:123',
fetch: (req) => api.getUser('123'),
);
print(user);
}
Flutter Setup
import 'package:flutter/material.dart';
import 'package:hive_ce_flutter/hive_ce_flutter.dart';
import 'package:syncache/syncache.dart';
import 'package:syncache_hive/syncache_hive.dart';
class User {
final int id;
final String name;
const User({required this.id, required this.name});
Map<String, dynamic> toJson() => {'id': id, 'name': name};
static User fromJson(Map<String, dynamic> json) =>
User(id: json['id'] as int, name: json['name'] as String);
}
class MyApp extends StatelessWidget {
const MyApp({required this.cache});
final Syncache<User> cache;
@override
Widget build(BuildContext context) => const SizedBox.shrink();
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Hive for Flutter
await Hive.initFlutter();
final store = await HiveStore.open<User>(
boxName: 'users',
fromJson: User.fromJson,
toJson: (user) => user.toJson(),
);
final cache = Syncache<User>(store: store);
runApp(MyApp(cache: cache));
}
Using Tags
// Store with tags for grouped invalidation
await cache.get(
key: 'calendar:events:2024-03',
fetch: fetchEvents,
tags: ['calendar', 'events', 'workspace:123'],
);
// Invalidate all entries with 'calendar' tag
await cache.invalidateTag('calendar');
Closing the Store
Remember to close the store when you're done:
await store.close();
API Reference
HiveStore
class HiveStore<T> implements TaggableStore<T> {
/// Opens a HiveStore with the specified box name.
static Future<HiveStore<T>> open<T>({
required String boxName,
required T Function(Map<String, dynamic>) fromJson,
required Map<String, dynamic> Function(T) toJson,
});
/// Closes the store and releases resources.
Future<void> close();
}
Inherited from TaggableStore
write(key, entry)- Store a valuewriteWithTags(key, entry, tags)- Store a value with tagsread(key)- Retrieve a valuedelete(key)- Delete a valueclear()- Clear all valuesgetTags(key)- Get tags for a keygetKeysByTag(tag)- Get all keys with a tagdeleteByTag(tag)- Delete all entries with a tagdeleteByTags(tags, {matchAll})- Delete entries matching tagsgetKeysByPattern(pattern)- Get keys matching a glob patterndeleteByPattern(pattern)- Delete keys matching a glob pattern
Limitations
- Key length: Hive limits keys to a maximum of 255 characters. Attempting to use longer keys will throw a
HiveError. - Tag replacement: Unlike
MemoryStore, callingwrite()on a key that already has tags will remove those tags. UsewriteWithTags()to explicitly set tags.
Serialization
HiveStore requires fromJson and toJson functions to serialize your data type. This is because Hive stores data as maps internally.
import 'package:syncache_hive/syncache_hive.dart';
class User {
final String name;
final String email;
User({required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
email: json['email'] as String,
);
}
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};
}
final store = HiveStore.open<User>(
boxName: 'users',
fromJson: User.fromJson,
toJson: (user) => user.toJson(),
);
License
MIT License - see LICENSE file for details.
Libraries
- syncache_hive
- Hive storage backend for Syncache.