Skip to content

Commit a47cd26

Browse files
committed
🎨 enhance container method to accept optional delimiter and update documentation
1 parent b020479 commit a47cd26

File tree

9 files changed

+217
-16
lines changed

9 files changed

+217
-16
lines changed

packages/hyper_storage/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
pubspec.lock
88

99
.idea/
10+
11+
doc/

packages/hyper_storage/README.md

Lines changed: 198 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
# hyper_storage
22

33
[![pub version](https://img.shields.io/pub/v/hyper_storage.svg)](https://pub.dev/packages/hyper_storage)
4-
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
54

6-
A simple and flexible key-value storage for Dart and Flutter applications, supporting multiple backends.
5+
A simple and unified key-value storage for Dart and Flutter applications, supporting multiple backends.
76

87
## Features
98

10-
-**Simple API:** Easy to use API for storing and retrieving data.
11-
-**Multiple Backends:** Supports different backends like `InMemory`, with more to come.
12-
-**Typed Storage:** Store and retrieve data with type safety.
13-
-**JSON Serialization:** Store and retrieve custom objects by providing `toJson` and `fromJson` functions.
14-
-**Named Containers:** Organize your data into named containers.
15-
-**Mockable:** Easy to mock for testing purposes.
9+
-**Simple API:** Easy to use API for storing and retrieving data.
10+
-**Multiple Backends:** Supports different backends like `InMemory`, `hive`, `shared_preferences`, and `secure_storage` (via separate packages).
11+
-**Typed Storage:** Store and retrieve data with type safety.
12+
-**JSON Serialization:** Store and retrieve custom objects by providing `toJson` and `fromJson` functions.
13+
-**Named Containers:** Organize your data into named containers for better structure.
14+
-**Asynchronous:** All operations are asynchronous, making it suitable for Flutter applications.
15+
-**Cross-Platform:** Works on mobile, web, and desktop platforms.
16+
-**Fully Tested:** Comprehensive test coverage to ensure reliability.
17+
-**Mockable:** Easy to mock for testing purposes.
1618

1719
## Getting started
1820

@@ -21,20 +23,27 @@ Add `hyper_storage` to your `pubspec.yaml` dependencies:
2123
```yaml
2224
dependencies:
2325
hyper_storage: ^0.1.0 # Replace with the latest version
26+
27+
hyper_storage_flutter: ^0.1.0 # Add this if you're using Flutter.
28+
29+
# Add one of the available backends of your choice:
30+
hyper_storage_hive: ^0.1.0
31+
hyper_storage_shared_preferences: ^0.1.0
32+
hyper_secure_storage: ^0.1.0
2433
```
2534
2635
Then, run `flutter pub get` or `dart pub get`.
2736

2837
## Usage
2938

30-
Initialize the storage with a backend. The `InMemoryBackend` is included by default for temporary storage.
39+
Initialize the storage with a backend of your choice.
3140

3241
```dart
3342
import 'package:hyper_storage/hyper_storage.dart';
3443
3544
void main() async {
3645
// Initialize the storage with InMemoryBackend
37-
final storage = await HyperStorage.init(backend: InMemoryBackend());
46+
final storage = await HyperStorage.init(backend: SharedPreferencesBackend());
3847
3948
// Set a value
4049
await storage.setString('name', 'Hyper Storage');
@@ -60,6 +69,185 @@ More backends are available in separate packages:
6069
- [hyper_storage_shared_preferences](https://pub.dev/packages/hyper_storage_shared_preferences): SharedPreferences backend for persistent storage.
6170
- [hyper_secure_storage](https://pub.dev/packages/hyper_secure_storage): Secure storage backend for sensitive data.
6271

72+
## Contents
73+
74+
- [Initialization](#initialization)
75+
- [Basic Operations](#basic-operations)
76+
- [Typed Data](#typed-data)
77+
- [JSON Data](#json-data)
78+
- [Named Containers](#named-containers)
79+
- [Object Containers](#object-containers)
80+
- [Checking for Keys](#checking-for-keys)
81+
- [Closing the Storage](#closing-the-storage)
82+
- [Mocking for Tests](#mocking-for-tests)
83+
84+
## Initialization
85+
86+
You can initialize `hyper_storage` with a specific backend. If no backend is provided, it defaults to `InMemoryBackend`.
87+
88+
### Default (In-Memory)
89+
90+
```dart
91+
import 'package:hyper_storage/hyper_storage.dart';
92+
93+
final storage = await HyperStorage.init(backend: InMemoryBackend());
94+
```
95+
96+
### Using Other Backends
97+
98+
To use other backends, you need to add the respective package to your `pubspec.yaml` and then provide the backend instance to the `init` method.
99+
100+
For example, to use the Hive backend:
101+
102+
```dart
103+
// Make sure to add hyper_storage_hive to your dependencies
104+
import 'package:hyper_storage_hive/hyper_storage_hive.dart';
105+
import 'package:hyper_storage/hyper_storage.dart';
106+
107+
final storage = await HyperStorage.init(backend: HiveBackend());
108+
```
109+
110+
## Basic Operations
111+
112+
You can use the `set` and `get` methods to store and retrieve data.
113+
114+
```dart
115+
// Set a value
116+
await storage.set('name', 'Hyper Storage');
117+
118+
// Get a value
119+
final name = await storage.get('name');
120+
print(name); // Output: Hyper Storage
121+
```
122+
123+
## Typed Data
124+
125+
`hyper_storage` provides typed methods to store and retrieve data with type safety.
126+
127+
### Storing Data
128+
129+
```dart
130+
await storage.setString('name', 'John');
131+
await storage.setInt('age', 30);
132+
await storage.setBool('isDeveloper', true);
133+
await storage.setDouble('height', 1.75);
134+
await storage.setStringList('skills', ['Dart', 'Flutter', 'JavaScript']);
135+
```
136+
137+
### Getting Data
138+
139+
```dart
140+
final String? name = await storage.getString('name');
141+
final int? age = await storage.getInt('age');
142+
final bool? isDeveloper = await storage.getBool('isDeveloper');
143+
final double? height = await storage.getDouble('height');
144+
final List<String>? skills = await storage.getStringList('skills');
145+
```
146+
147+
## JSON Data
148+
149+
You can store and retrieve JSON data (`Map<String, dynamic>`) and lists of JSON data (`List<Map<String, dynamic>>`).
150+
151+
### Storing JSON
152+
153+
```dart
154+
await storage.setJson('profile', {
155+
'name': 'John Doe',
156+
'age': 30,
157+
'isDeveloper': true,
158+
'height': 1.75,
159+
'skills': ['Dart', 'Flutter', 'JavaScript'],
160+
});
161+
162+
await storage.setJsonList('items', [
163+
{'id': 1, 'name': 'Item 1'},
164+
{'id': 2, 'name': 'Item 2'},
165+
{'id': 3, 'name': 'Item 3'},
166+
]);
167+
```
168+
169+
### Getting JSON
170+
171+
```dart
172+
final Map<String, dynamic>? profile = await storage.getJson('profile');
173+
final List<Map<String, dynamic>>? items = await storage.getJsonList('items');
174+
```
175+
176+
## Named Containers
177+
178+
You can use named containers to organize your data.
179+
180+
```dart
181+
final container = await HyperStorage.container('account');
182+
await container.setString('username', 'john_doe');
183+
final String? username = await container.getString('username');
184+
```
185+
186+
## Object Containers
187+
188+
You can store and retrieve custom objects by providing `toJson` and `fromJson` functions.
189+
190+
```dart
191+
class User {
192+
final String name;
193+
final int age;
194+
195+
User({required this.name, required this.age});
196+
197+
factory User.fromJson(Map<String, dynamic> json) {
198+
return User(name: json['name'], age: json['age']);
199+
}
200+
201+
Map<String, dynamic> toJson() {
202+
return {'name': name, 'age': age};
203+
}
204+
}
205+
206+
final storage = await HyperStorage.objectContainer<User>(
207+
'users',
208+
toJson: (user) => user.toJson(),
209+
fromJson: User.fromJson,
210+
);
211+
212+
await storage.set('user1', User(name: 'John', age: 23));
213+
final User? user = await storage.get('user1');
214+
final List<User> users = await storage.getValues();
215+
final Map<String, User> allUsers = await storage.getAll();
216+
```
217+
218+
## Checking for Keys
219+
220+
You can check if a key exists in the storage.
221+
222+
```dart
223+
final bool containsName = await storage.containsKey('name');
224+
```
225+
226+
## Closing the Storage
227+
228+
It's important to close the storage when it's no longer needed to release resources.
229+
230+
```dart
231+
await storage.close(); // closes all containers.
232+
```
233+
234+
## Mocking for Tests
235+
236+
For testing, you can use a mocked version of the storage.
237+
238+
```dart
239+
final storage = await HyperStorage.initMocked();
240+
```
241+
242+
You can also provide initial data to the mocked storage.
243+
244+
```dart
245+
final storage = await HyperStorage.initMocked(initialData: {
246+
'name': 'Test',
247+
'age': 25,
248+
});
249+
```
250+
63251
## Contributing
64252

65253
Contributions are welcome! Please feel free to open an issue or submit a pull request.

packages/hyper_storage/analysis_options.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ linter:
1111
use_super_parameters: true
1212
prefer_relative_imports: true
1313
public_member_api_docs: true
14+
comment_references: true
1415

1516
formatter:
1617
page_width: 120

packages/hyper_storage/lib/hyper_storage.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44
library;
55

6+
export 'src/api/api.dart';
67
export 'src/api/backend.dart' hide GenericStorageOperationsMixin;
78
export 'src/api/listenable.dart' hide ListenableStorage;
89
export 'src/api/serializable_container.dart';

packages/hyper_storage/lib/src/api/backend.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ abstract class StorageBackend with GenericStorageOperationsMixin implements Stor
3838
/// you to organize data into logical groups without key collisions.
3939
///
4040
/// Parameters:
41-
/// * [name] - The unique name for the container. This is used to namespace
41+
/// - [name] - The unique name for the container. This is used to namespace
4242
/// all keys within the container.
43+
/// - [delimiter] - Optional. The character(s) used to separate the container name.
44+
/// If not provided, the default delimiter defined in [StorageContainer.defaultDelimiter]
4345
///
4446
/// Returns a [Future] that completes with a new [HyperStorageContainer]
4547
/// instance configured to use this backend.
4648
///
4749
/// Throws:
4850
/// * [ArgumentError] if the name is empty, contains only whitespace, or
4951
/// contains invalid characters.
50-
Future<HyperStorageContainer> container(String name) async => HyperStorageContainer(backend: this, name: name);
52+
Future<HyperStorageContainer> container(String name, {String? delimiter}) async => HyperStorageContainer(
53+
backend: this,
54+
name: name,
55+
delimiter: delimiter,
56+
);
5157

5258
@override
5359
Future<bool> get isEmpty async {

packages/hyper_storage_hive/lib/src/backend.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ class HiveBackend extends StorageBackend {
4646
Future<void> init() async => _box ??= await Hive.openBox(name);
4747

4848
@override
49-
Future<HyperStorageContainer> container(String name) async {
49+
Future<HyperStorageContainer> container(String name, {String? delimiter}) async {
5050
final backend = HiveBackend(boxName: name);
5151
await backend.init();
52-
return HyperStorageContainer(backend: backend, name: name);
52+
return HyperStorageContainer(backend: backend, name: name, delimiter: delimiter);
5353
}
5454

5555
@override

packages/hyper_storage_hive/lib/src/lazy_backend.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ class LazyHiveBackend extends StorageBackend {
4747
///
4848
/// This method creates a new box with the given [name] and initializes it.
4949
@override
50-
Future<HyperStorageContainer> container(String name) async {
50+
Future<HyperStorageContainer> container(String name, {String? delimiter}) async {
5151
final backend = LazyHiveBackend(boxName: name);
5252
await backend.init();
53-
return HyperStorageContainer(backend: backend, name: name);
53+
return HyperStorageContainer(backend: backend, name: name, delimiter: delimiter);
5454
}
5555

5656
@override

scripts.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ test:
1313
- cd packages/hyper_secure_storage && flutter test
1414
- cd packages/hyper_storage_flutter && flutter test
1515

16+
doc:
17+
- cd packages/hyper_storage && rm -rf doc && dart doc
18+
1619
format: dart format --fix .

0 commit comments

Comments
 (0)