Skip to content

Commit 4d5cd35

Browse files
committed
📝 update docs
1 parent 9f2d2df commit 4d5cd35

File tree

5 files changed

+26
-129
lines changed

5 files changed

+26
-129
lines changed

packages/hyper_storage/docs/reactivity.md

Lines changed: 18 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ Listening to changes for a specific key allows you to react only when that parti
2121

2222
```dart
2323
// Register a listener for a specific key
24-
storage.addKeyListener
25-
('name
26-
'
27-
, onKeyChanged);
24+
storage.addKeyListener('name', onKeyChanged);
2825
2926
void onKeyChanged() async {
30-
final newValue = await storage.getString('name');
31-
print('The value of "name" has changed to: $newValue');
27+
final newValue = await storage.getString('name');
28+
print('The value of "name" has changed to: $newValue');
3229
}
3330
3431
// unregister the listener
@@ -39,18 +36,14 @@ You can also listen to key changes in a named container:
3936

4037
```dart
4138
42-
final container = await
43-
storage.container
44-
('user
45-
'
46-
);
39+
final container = await storage.container('user');
4740
4841
// Register a listener for a specific key in the container
4942
container.addKeyListener('email', onEmailChanged);
5043
5144
void onEmailChanged() async {
52-
final newEmail = await container.getString('email');
53-
print('The email has changed to: $newEmail');
45+
final newEmail = await container.getString('email');
46+
print('The email has changed to: $newEmail');
5447
}
5548
5649
// unregister the listener
@@ -66,22 +59,15 @@ Item holders itself only holds a single value, so you don't need to specify a ke
6659
final itemHolder = storage.itemHolder<String>('status');
6760
6861
// Register a listener for changes in the item holder
69-
itemHolder.addListener
70-
(
71-
onStatusChanged);
62+
itemHolder.addListener(onStatusChanged);
7263
7364
void onStatusChanged() async {
74-
final newStatus = await itemHolder.get();
75-
print('The status has changed to: $newStatus');
65+
final newStatus = await itemHolder.get();
66+
print('The status has changed to: $newStatus');
7667
}
7768
7869
// unregister the listener
79-
itemHolder
80-
.
81-
removeListener
82-
(
83-
onStatusChanged
84-
);
70+
itemHolder.removeListener(onStatusChanged);
8571
```
8672

8773
## Listening to All Changes
@@ -90,47 +76,31 @@ You can listen to all changes in the storage, regardless of which key was modifi
9076

9177
```dart
9278
// Register a listener for all changes
93-
storage.addListener
94-
(
95-
onStorageChanged);
79+
storage.addListener(onStorageChanged);
9680
9781
void onStorageChanged() {
98-
print('The storage has changed.');
82+
print('The storage has changed.');
9983
}
10084
10185
// unregister the listener
102-
storage
103-
.
104-
removeListener
105-
(
106-
onStorageChanged
107-
);
86+
storage.removeListener(onStorageChanged);
10887
```
10988

11089
You can also listen to all changes in a named container:
11190

11291
```dart
11392
114-
final container = await
115-
storage.container
116-
('settings
117-
'
118-
);
93+
final container = await storage.container('settings');
11994
12095
// Register a listener for all changes in the container
12196
container.addListener(onSettingsChanged);
12297
12398
void onSettingsChanged() {
124-
print('The settings container has changed.');
99+
print('The settings container has changed.');
125100
}
126101
127102
// unregister the listener
128-
container
129-
.
130-
removeListener
131-
(
132-
onSettingsChanged
133-
);
103+
container.removeListener(onSettingsChanged);
134104
```
135105

136106
# Streaming Item Holder Changes
@@ -150,8 +120,7 @@ final subscription = itemHolder.listen((newStatus) {
150120
});
151121
152122
// Don't forget to cancel the subscription when it's no longer needed
153-
subscription.cancel
154-
();
123+
subscription.cancel();
155124
```
156125

157126
## Using with StreamBuilder in Flutter
@@ -251,8 +220,7 @@ StreamBuilder<String?>(
251220

252221
This means calling `storage.stream('key')` directly in a build method is safe and will not create multiple streams.
253222

254-
**Recommended Pattern: Use ItemHolder Directly**: If you have an `ItemHolder` for the key, you can use it directly in
255-
the `StreamBuilder`. This is the most efficient and clear approach.
223+
If you have an `ItemHolder` for the key, you can use it directly in the `StreamBuilder`. This is the most efficient and clear approach.
256224

257225
```dart
258226
class _MyWidgetState extends State<MyWidget> {
@@ -281,85 +249,6 @@ class _MyWidgetState extends State<MyWidget> {
281249
}
282250
```
283251

284-
**Why ItemHolder is recommended:**
285-
286-
- **Clear intent**: Makes it obvious you're using a managed stream
287-
- **Value caching**: Uses `BehaviorSubject` - new listeners get the cached value immediately
288-
- **Efficient**: Single persistent stream with lazy activation
289-
- **Multiple listeners**: Supports many concurrent listeners without duplicating work
290-
- **No error emissions**: Transient failures don't get cached and replayed
291-
292-
### **Also Acceptable: Cache the stream in a variable**
293-
294-
If you prefer to use the `stream()` method, you can cache it in a `late final` variable.
295-
Since `stream()` returns a cached `ItemHolder`, this is now equivalent to Pattern 1:
296-
297-
```dart
298-
class MyWidget extends StatefulWidget {
299-
@override
300-
State<MyWidget> createState() => _MyWidgetState();
301-
}
302-
303-
class _MyWidgetState extends State<MyWidget> {
304-
// Cache the stream - actually returns the same ItemHolder as itemHolder<String>('name')
305-
late final Stream<String?> nameStream = storage.stream<String>('name');
306-
307-
@override
308-
Widget build(BuildContext context) {
309-
return StreamBuilder<String?>(
310-
stream: nameStream, // ✅ SAFE: Same cached ItemHolder instance
311-
builder: (context, snapshot) {
312-
return Text(snapshot.data ?? 'Unknown');
313-
},
314-
);
315-
}
316-
317-
@override
318-
void dispose() {
319-
// If using stream(), you can cast to dispose if needed
320-
if (nameStream is ItemHolder) {
321-
(nameStream as ItemHolder).dispose();
322-
}
323-
super.dispose();
324-
}
325-
}
326-
```
327-
328-
### **Create stream in `initState()`**
329-
330-
You can also create the stream in `initState()`:
331-
332-
```dart
333-
class _MyWidgetState extends State<MyWidget> {
334-
late Stream<String?> nameStream;
335-
336-
@override
337-
void initState() {
338-
super.initState();
339-
nameStream = storage.stream<String>('name'); // Returns cached ItemHolder
340-
}
341-
342-
@override
343-
Widget build(BuildContext context) {
344-
return StreamBuilder<String?>(
345-
stream: nameStream, // ✅ SAFE: Same cached instance
346-
builder: (context, snapshot) {
347-
return Text(snapshot.data ?? 'Unknown');
348-
},
349-
);
350-
}
351-
}
352-
```
353-
354-
### Summary: Which pattern should you use?
355-
356-
| Pattern | Recommended? | Notes |
357-
|--------------------------------|-----------------------------------|----------------------------------------------------------------------------|
358-
| **ItemHolder directly** |**Best** | Most explicit. Clear intent. Direct access to ItemHolder API. |
359-
| **Cached stream (late final)** | ✅ Good | Same as above but less explicit. `stream()` returns ItemHolder internally. |
360-
| **initState stream** | ✅ Good | Useful for complex initialization. Still returns cached ItemHolder. |
361-
| **Direct stream() in build()** | ⚠️ **Acceptable but discouraged** | Now safe (returns cached instance) but not recommended for code clarity. |
362-
363252
## Streaming with Serializable Containers
364253

365254
You can also stream changes in a `SerializableContainer`. This is useful when you want to listen to changes in a complex

packages/hyper_storage_flutter/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A package that makes it easy to use `hyper_storage` in Flutter applications.
44

5+
### [Full Documentation](https://pub.dev/documentation/hyper_storage/latest)
6+
57
## Features
68

79
- **ValueListenable Support:** Listen to changes in your storage using `ValueListenable`.

packages/hyper_storage_hive/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
A backend for `hyper_storage` that uses `hive_ce` for local data storage.
77

8+
### [Full Documentation](https://pub.dev/documentation/hyper_storage/latest)
9+
810
## Features
911

1012
- **Persistent Storage:** Persists data on the device using Hive.

packages/hyper_storage_secure/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
A backend for `hyper_storage` that uses `flutter_secure_storage` for secure data storage.
77

8+
### [Full Documentation](https://pub.dev/documentation/hyper_storage/latest)
9+
810
## Features
911

1012
- **Secure Storage:** Securely persists data on the device using `flutter_secure_storage`.

packages/hyper_storage_shared_preferences/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
A backend for `hyper_storage` that uses `shared_preferences` for Flutter applications.
77

8+
### [Full Documentation](https://pub.dev/documentation/hyper_storage/latest)
9+
810
## Features
911

1012
- **Persistent Storage:** Persists data on the device using `shared_preferences`.

0 commit comments

Comments
 (0)