@biglogic/rgs 3.7.6 → 3.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COPYRIGHT.md +4 -4
- package/FUNDING.yml +12 -12
- package/LICENSE.md +9 -9
- package/README.md +470 -470
- package/SECURITY.md +13 -13
- package/docs/README.md +470 -470
- package/docs/SUMMARY.md +64 -64
- package/docs/_config.yml +1 -1
- package/docs/chapters/01-philosophy.md +54 -54
- package/docs/chapters/02-getting-started.md +68 -68
- package/docs/chapters/03-the-magnetar-way.md +69 -69
- package/docs/chapters/04-persistence-and-safety.md +125 -125
- package/docs/chapters/05-plugins-and-extensibility.md +190 -190
- package/docs/chapters/06-case-studies.md +69 -69
- package/docs/chapters/08-migration-guide.md +284 -284
- package/docs/chapters/09-security-architecture.md +50 -50
- package/docs/chapters/10-local-first-sync.md +146 -146
- package/docs/qa.md +47 -47
- package/package.json +91 -74
- package/rgs-extension.vsix +0 -0
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
# 🏗️ Chapter 4: Persistence and Safety - Built like a Tank
|
|
2
|
-
|
|
3
|
-
In a real-world application, state that vanishes on page refresh is a developer failure. RGS handles data saving **intelligently**.
|
|
4
|
-
|
|
5
|
-
## 💾 Persistence: "Set and Forget"
|
|
6
|
-
|
|
7
|
-
When you initialize RGS or a Magnetar, you can enable persistence. But it's not a simple `localStorage.set`.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
initState({
|
|
11
|
-
persist: true,
|
|
12
|
-
storage: 'local' // or 'session', or a custom adapter
|
|
13
|
-
});
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
### Advanced Storage: Beyond 5MB
|
|
17
|
-
|
|
18
|
-
For applications that need to store massive amounts of data (Gigabytes), standard `localStorage` is not enough. RGS provides official plugins for advanced scenarios:
|
|
19
|
-
|
|
20
|
-
| Technology | Capacity | Purpose | Plugin |
|
|
21
|
-
| :--- | :--- | :--- | :--- |
|
|
22
|
-
| **LocalStorage** | ~5MB | Basic UI settings, small profiles. | Core (Native) |
|
|
23
|
-
| **IndexedDB** | GBs | Offline-first apps, large datasets, logs. | `indexedDBPlugin` |
|
|
24
|
-
| **Cloud Sync** | Unlimited | Remote backup, cross-device sync. | `cloudSyncPlugin` |
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## ☁️ Hybrid Persistence: The "Cloud-Cloud" Strategy
|
|
29
|
-
|
|
30
|
-
RGS allows you to combine local power with cloud safety. You can store your active data in **IndexedDB** for speed and capacity, while automatically backing it up to a remote database (MongoDB, Firebase, SQL) using the **Cloud Sync Plugin**.
|
|
31
|
-
|
|
32
|
-
### Why use Cloud Sync?
|
|
33
|
-
- **Differential Updates**: Safely sends only what was changed since the last sync.
|
|
34
|
-
- **Scheduled or On-Demand**: Sync every 5 minutes automatically, or triggered by a "Save to Cloud" button.
|
|
35
|
-
- **Diagnostics**: Track how much data you are syncing and detect errors before they reach the user.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
### What happens under the hood?
|
|
40
|
-
|
|
41
|
-
```mermaid
|
|
42
|
-
sequenceDiagram
|
|
43
|
-
participant C as Component
|
|
44
|
-
participant RGS as Globo State
|
|
45
|
-
participant S as LocalStorage
|
|
46
|
-
|
|
47
|
-
Note over C,RGS: User clicks a button
|
|
48
|
-
C->>RGS: set('count', 10)
|
|
49
|
-
RGS-->>C: Update UI (Instant)
|
|
50
|
-
|
|
51
|
-
Note over RGS: Waiting 300ms (Debounce)
|
|
52
|
-
|
|
53
|
-
RGS->>S: Write to Disk
|
|
54
|
-
Note right of S: Data saved successfully
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
- **Debouncing**: If you update the state 100 times in one second, RGS writes to the disk only once at the end. This saves battery life and browser performance.
|
|
58
|
-
- **Selective Persistence**: Don't want to save everything? You can tell RGS which keys to ignore or which ones to save only temporarily.
|
|
59
|
-
|
|
60
|
-
## 🛡️ Immutability: The Immer Shield
|
|
61
|
-
|
|
62
|
-
Have you ever had bugs where state changed "mysteriously" because you mutated an array directly? RGS uses **Immer** at its core (the Stellar Engine).
|
|
63
|
-
|
|
64
|
-
**Dangerous Code (Standard JS):**
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
const user = store.get('user');
|
|
68
|
-
user.permissions.push('admin'); // BOOM! You mutated the original without triggering a re-render.
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**The RGS Way:**
|
|
72
|
-
|
|
73
|
-
```javascript
|
|
74
|
-
store.set('user', (draft) => {
|
|
75
|
-
draft.permissions.push('admin'); // SAFE! RGS creates an immutable copy for you.
|
|
76
|
-
});
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 🕵️ Validation: Schema Plugin
|
|
80
|
-
|
|
81
|
-
Never trust data coming back from the server or saved in the browser 6 months ago. Use the **schemaPlugin**.
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
import { schemaPlugin } from '@biglogic/rgs';
|
|
85
|
-
import { z } from 'zod'; // Recommended!
|
|
86
|
-
|
|
87
|
-
const store = initState();
|
|
88
|
-
store._addPlugin(schemaPlugin({
|
|
89
|
-
price: (val) => typeof val === 'number' && val > 0,
|
|
90
|
-
email: (val) => val.includes('@')
|
|
91
|
-
}));
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
If anyone tries to `set('price', -50)`, RGS will block the operation and warn you. **Clean State = Happy App.**
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## ⚠️ Size Limits: maxObjectSize & maxTotalSize
|
|
99
|
-
|
|
100
|
-
Protect your app from memory issues with automatic size warnings:
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
const store = initState({
|
|
104
|
-
// Warn if single value exceeds 5MB (default: 5MB)
|
|
105
|
-
maxObjectSize: 5 * 1024 * 1024,
|
|
106
|
-
// Warn if total store exceeds 50MB (default: 50MB)
|
|
107
|
-
maxTotalSize: 50 * 1024 * 1024
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Setting a value that exceeds the limit will trigger a warning
|
|
111
|
-
store.set('largeData', bigObject); // Warns if > maxObjectSize
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## 💡 Case Study: The Cart that Never Lost an Item
|
|
117
|
-
|
|
118
|
-
**Challenge**: User adds products, closes the browser, comes back after two days. The cart must still be there, and synced with their account on other devices.
|
|
119
|
-
**RGS Solution**:
|
|
120
|
-
|
|
121
|
-
1. Enable `indexedDBPlugin` for robust local storage (handles thousands of items).
|
|
122
|
-
2. Use `cloudSyncPlugin` to bridge the local state with your company's MongoDB Atlas or Firebase.
|
|
123
|
-
3. Result? 5-star UX with full data durability and cross-device sync.
|
|
124
|
-
|
|
125
|
-
**Next step:** [Ecosystem and Plugins: Extending the Power](05-plugins-and-extensibility.md)
|
|
1
|
+
# 🏗️ Chapter 4: Persistence and Safety - Built like a Tank
|
|
2
|
+
|
|
3
|
+
In a real-world application, state that vanishes on page refresh is a developer failure. RGS handles data saving **intelligently**.
|
|
4
|
+
|
|
5
|
+
## 💾 Persistence: "Set and Forget"
|
|
6
|
+
|
|
7
|
+
When you initialize RGS or a Magnetar, you can enable persistence. But it's not a simple `localStorage.set`.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
initState({
|
|
11
|
+
persist: true,
|
|
12
|
+
storage: 'local' // or 'session', or a custom adapter
|
|
13
|
+
});
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Advanced Storage: Beyond 5MB
|
|
17
|
+
|
|
18
|
+
For applications that need to store massive amounts of data (Gigabytes), standard `localStorage` is not enough. RGS provides official plugins for advanced scenarios:
|
|
19
|
+
|
|
20
|
+
| Technology | Capacity | Purpose | Plugin |
|
|
21
|
+
| :--- | :--- | :--- | :--- |
|
|
22
|
+
| **LocalStorage** | ~5MB | Basic UI settings, small profiles. | Core (Native) |
|
|
23
|
+
| **IndexedDB** | GBs | Offline-first apps, large datasets, logs. | `indexedDBPlugin` |
|
|
24
|
+
| **Cloud Sync** | Unlimited | Remote backup, cross-device sync. | `cloudSyncPlugin` |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ☁️ Hybrid Persistence: The "Cloud-Cloud" Strategy
|
|
29
|
+
|
|
30
|
+
RGS allows you to combine local power with cloud safety. You can store your active data in **IndexedDB** for speed and capacity, while automatically backing it up to a remote database (MongoDB, Firebase, SQL) using the **Cloud Sync Plugin**.
|
|
31
|
+
|
|
32
|
+
### Why use Cloud Sync?
|
|
33
|
+
- **Differential Updates**: Safely sends only what was changed since the last sync.
|
|
34
|
+
- **Scheduled or On-Demand**: Sync every 5 minutes automatically, or triggered by a "Save to Cloud" button.
|
|
35
|
+
- **Diagnostics**: Track how much data you are syncing and detect errors before they reach the user.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### What happens under the hood?
|
|
40
|
+
|
|
41
|
+
```mermaid
|
|
42
|
+
sequenceDiagram
|
|
43
|
+
participant C as Component
|
|
44
|
+
participant RGS as Globo State
|
|
45
|
+
participant S as LocalStorage
|
|
46
|
+
|
|
47
|
+
Note over C,RGS: User clicks a button
|
|
48
|
+
C->>RGS: set('count', 10)
|
|
49
|
+
RGS-->>C: Update UI (Instant)
|
|
50
|
+
|
|
51
|
+
Note over RGS: Waiting 300ms (Debounce)
|
|
52
|
+
|
|
53
|
+
RGS->>S: Write to Disk
|
|
54
|
+
Note right of S: Data saved successfully
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **Debouncing**: If you update the state 100 times in one second, RGS writes to the disk only once at the end. This saves battery life and browser performance.
|
|
58
|
+
- **Selective Persistence**: Don't want to save everything? You can tell RGS which keys to ignore or which ones to save only temporarily.
|
|
59
|
+
|
|
60
|
+
## 🛡️ Immutability: The Immer Shield
|
|
61
|
+
|
|
62
|
+
Have you ever had bugs where state changed "mysteriously" because you mutated an array directly? RGS uses **Immer** at its core (the Stellar Engine).
|
|
63
|
+
|
|
64
|
+
**Dangerous Code (Standard JS):**
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const user = store.get('user');
|
|
68
|
+
user.permissions.push('admin'); // BOOM! You mutated the original without triggering a re-render.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**The RGS Way:**
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
store.set('user', (draft) => {
|
|
75
|
+
draft.permissions.push('admin'); // SAFE! RGS creates an immutable copy for you.
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 🕵️ Validation: Schema Plugin
|
|
80
|
+
|
|
81
|
+
Never trust data coming back from the server or saved in the browser 6 months ago. Use the **schemaPlugin**.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { schemaPlugin } from '@biglogic/rgs';
|
|
85
|
+
import { z } from 'zod'; // Recommended!
|
|
86
|
+
|
|
87
|
+
const store = initState();
|
|
88
|
+
store._addPlugin(schemaPlugin({
|
|
89
|
+
price: (val) => typeof val === 'number' && val > 0,
|
|
90
|
+
email: (val) => val.includes('@')
|
|
91
|
+
}));
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If anyone tries to `set('price', -50)`, RGS will block the operation and warn you. **Clean State = Happy App.**
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## ⚠️ Size Limits: maxObjectSize & maxTotalSize
|
|
99
|
+
|
|
100
|
+
Protect your app from memory issues with automatic size warnings:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
const store = initState({
|
|
104
|
+
// Warn if single value exceeds 5MB (default: 5MB)
|
|
105
|
+
maxObjectSize: 5 * 1024 * 1024,
|
|
106
|
+
// Warn if total store exceeds 50MB (default: 50MB)
|
|
107
|
+
maxTotalSize: 50 * 1024 * 1024
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Setting a value that exceeds the limit will trigger a warning
|
|
111
|
+
store.set('largeData', bigObject); // Warns if > maxObjectSize
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 💡 Case Study: The Cart that Never Lost an Item
|
|
117
|
+
|
|
118
|
+
**Challenge**: User adds products, closes the browser, comes back after two days. The cart must still be there, and synced with their account on other devices.
|
|
119
|
+
**RGS Solution**:
|
|
120
|
+
|
|
121
|
+
1. Enable `indexedDBPlugin` for robust local storage (handles thousands of items).
|
|
122
|
+
2. Use `cloudSyncPlugin` to bridge the local state with your company's MongoDB Atlas or Firebase.
|
|
123
|
+
3. Result? 5-star UX with full data durability and cross-device sync.
|
|
124
|
+
|
|
125
|
+
**Next step:** [Ecosystem and Plugins: Extending the Power](05-plugins-and-extensibility.md)
|
|
@@ -1,190 +1,190 @@
|
|
|
1
|
-
# 🔌 Chapter 5: Ecosystem and Plugins - Become a Power User
|
|
2
|
-
|
|
3
|
-
RGS is not a closed box. It's a modular engine that you can extend to cover every business need. All plugins are designed to be "Plug & Play".
|
|
4
|
-
|
|
5
|
-
## 🔌 Available Plugins
|
|
6
|
-
|
|
7
|
-
RGS includes 11 official plugins:
|
|
8
|
-
|
|
9
|
-
| Plugin | Purpose | Import |
|
|
10
|
-
|--------|---------|--------|
|
|
11
|
-
| `devToolsPlugin` | Redux DevTools integration | `rgs` |
|
|
12
|
-
| `debugPlugin` | Console debug access (DEV only) | `rgs` |
|
|
13
|
-
| `indexedDBPlugin` | GB-scale Local Storage | `rgs/advanced` |
|
|
14
|
-
| `cloudSyncPlugin` | Remote Cloud Backup/Sync | `rgs/advanced` |
|
|
15
|
-
| `syncPlugin` | Cross-tab synchronization | `rgs/advanced` |
|
|
16
|
-
| `immerPlugin` | Immer for mutable-style updates | `rgs` |
|
|
17
|
-
| `snapshotPlugin` | Save/restore state snapshots | `rgs` |
|
|
18
|
-
| `undoRedoPlugin` | History management | `rgs` |
|
|
19
|
-
| `schemaPlugin` | Schema validation | `rgs` |
|
|
20
|
-
| `guardPlugin` | Pre-set value transformation | `rgs` |
|
|
21
|
-
| `analyticsPlugin` | Track state changes | `rgs` |
|
|
22
|
-
|
|
23
|
-
## 🔎 1. DevTools: See Under the Hood
|
|
24
|
-
|
|
25
|
-
Import the official plugin and you'll see every state change, transaction, and execution time in the console or dev tools (Redux DevTools support included!).
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import { devToolsPlugin } from '@biglogic/rgs';
|
|
29
|
-
|
|
30
|
-
store._addPlugin(devToolsPlugin({ name: 'My Store' }));
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 🐛 2. Debug: Console Access (DEV ONLY)
|
|
34
|
-
|
|
35
|
-
⚠️ **FOR DEVELOPMENT ONLY** - This plugin is automatically disabled in production.
|
|
36
|
-
|
|
37
|
-
Access your store directly from the browser console:
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { debugPlugin } from '@biglogic/rgs';
|
|
41
|
-
|
|
42
|
-
// Always wrap in dev check
|
|
43
|
-
if (process.env.NODE_ENV === 'development') {
|
|
44
|
-
store._addPlugin(debugPlugin())
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Then in the browser console:
|
|
49
|
-
```javascript
|
|
50
|
-
gstate.list() // View all state
|
|
51
|
-
gstate.get('key') // Get a value
|
|
52
|
-
gstate.set('key', val) // Set a value
|
|
53
|
-
gstate.info() // Store info
|
|
54
|
-
gstate.banner() // Show help
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## 2. Cross-Tab Sync: Multi-Tab Magic
|
|
58
|
-
|
|
59
|
-
Have your app open in three browser tabs? With the `syncPlugin`, if a user changes the theme in one tab, all other tabs update instantly. **Without hitting the server.**
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { syncPlugin } from 'rgs/advanced';
|
|
63
|
-
|
|
64
|
-
store._addPlugin(syncPlugin({ channelName: 'my_app_sync' }));
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## 🔐 3. Encode Option: Base64 Encoding
|
|
68
|
-
|
|
69
|
-
Use the `encoded` option for simple base64 encoding (not encryption, just obfuscation):
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// Per-value encoding
|
|
73
|
-
store.set('token', 'secret-value', { persist: true, encoded: true })
|
|
74
|
-
|
|
75
|
-
// Or global encoding for all persisted values
|
|
76
|
-
const store = initState({ encoded: true })
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
> **Note:** Use `encryptionKey` with AES-256-GCM for real security. The `encoded` option is just simple obfuscation.
|
|
80
|
-
|
|
81
|
-
## 🕐 4. TTL (Time To Live): Expiring Data
|
|
82
|
-
|
|
83
|
-
Use the `ttl` option in persist to make data expire automatically:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
store.set('session_token', tokenValue, {
|
|
87
|
-
persist: true,
|
|
88
|
-
ttl: 3600000 // Expires in 1 hour
|
|
89
|
-
});
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## 🎲 5. Undo/Redo: History Management
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
import { undoRedoPlugin } from '@biglogic/rgs';
|
|
96
|
-
|
|
97
|
-
store._addPlugin(undoRedoPlugin({ limit: 50 }));
|
|
98
|
-
|
|
99
|
-
// Later...
|
|
100
|
-
store.undo();
|
|
101
|
-
store.redo();
|
|
102
|
-
store.canUndo(); // boolean
|
|
103
|
-
store.canRedo(); // boolean
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## 📸 6. Snapshots: Save & Restore State
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { snapshotPlugin } from '@biglogic/rgs';
|
|
110
|
-
|
|
111
|
-
store._addPlugin(snapshotPlugin());
|
|
112
|
-
|
|
113
|
-
// Save current state
|
|
114
|
-
store.takeSnapshot('backup_1');
|
|
115
|
-
|
|
116
|
-
// Restore
|
|
117
|
-
store.restoreSnapshot('backup_1');
|
|
118
|
-
|
|
119
|
-
// List all snapshots
|
|
120
|
-
store.listSnapshots(); // ['backup_1', ...]
|
|
121
|
-
|
|
122
|
-
// Delete
|
|
123
|
-
store.deleteSnapshot('backup_1');
|
|
124
|
-
store.clearSnapshots();
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## 🛡️ 7. Guard: Pre-Set Transformation
|
|
128
|
-
|
|
129
|
-
Transform values before they hit the store:
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
import { guardPlugin } from '@biglogic/rgs';
|
|
133
|
-
|
|
134
|
-
store._addPlugin(guardPlugin({
|
|
135
|
-
'user_input': (val) => val.trim().toLowerCase()
|
|
136
|
-
}));
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## ✅ 8. Schema: Validation
|
|
140
|
-
|
|
141
|
-
Validate values before setting:
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
import { schemaPlugin } from '@biglogic/rgs';
|
|
145
|
-
|
|
146
|
-
store._addPlugin(schemaPlugin({
|
|
147
|
-
'email': (val) => {
|
|
148
|
-
if (typeof val !== 'string') return 'Must be a string';
|
|
149
|
-
return val.includes('@') ? true : 'Invalid email';
|
|
150
|
-
}
|
|
151
|
-
}));
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## 📊 9. Analytics: Track Changes
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
import { analyticsPlugin } from '@biglogic/rgs';
|
|
158
|
-
|
|
159
|
-
store._addPlugin(analyticsPlugin({
|
|
160
|
-
provider: (event) => {
|
|
161
|
-
console.log('State changed:', event);
|
|
162
|
-
// Send to analytics service
|
|
163
|
-
},
|
|
164
|
-
keys: ['user', 'cart'] // Only track these keys
|
|
165
|
-
}));
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## 🔄 10. Immer Integration
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
import { immerPlugin } from '@biglogic/rgs';
|
|
172
|
-
|
|
173
|
-
store._addPlugin(immerPlugin());
|
|
174
|
-
|
|
175
|
-
// Update nested state with Immer
|
|
176
|
-
store.setWithProduce('user', (draft) => {
|
|
177
|
-
draft.name = 'New Name';
|
|
178
|
-
draft.address.city = 'New City';
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## 💡 A Word of Wisdom for Easy & Advanced Scenarios
|
|
185
|
-
|
|
186
|
-
Plugins are used to **abstract the boring logic**. If you find yourself writing the same `useEffect` to sync two things in 5 different parts of your app... **Stop.** Create a plugin or use an existing one.
|
|
187
|
-
|
|
188
|
-
The best code is the code you write once and forget about.
|
|
189
|
-
|
|
190
|
-
**Next step:** [Case Studies: Real-World Production Strategies](06-case-studies.md)
|
|
1
|
+
# 🔌 Chapter 5: Ecosystem and Plugins - Become a Power User
|
|
2
|
+
|
|
3
|
+
RGS is not a closed box. It's a modular engine that you can extend to cover every business need. All plugins are designed to be "Plug & Play".
|
|
4
|
+
|
|
5
|
+
## 🔌 Available Plugins
|
|
6
|
+
|
|
7
|
+
RGS includes 11 official plugins:
|
|
8
|
+
|
|
9
|
+
| Plugin | Purpose | Import |
|
|
10
|
+
|--------|---------|--------|
|
|
11
|
+
| `devToolsPlugin` | Redux DevTools integration | `rgs` |
|
|
12
|
+
| `debugPlugin` | Console debug access (DEV only) | `rgs` |
|
|
13
|
+
| `indexedDBPlugin` | GB-scale Local Storage | `rgs/advanced` |
|
|
14
|
+
| `cloudSyncPlugin` | Remote Cloud Backup/Sync | `rgs/advanced` |
|
|
15
|
+
| `syncPlugin` | Cross-tab synchronization | `rgs/advanced` |
|
|
16
|
+
| `immerPlugin` | Immer for mutable-style updates | `rgs` |
|
|
17
|
+
| `snapshotPlugin` | Save/restore state snapshots | `rgs` |
|
|
18
|
+
| `undoRedoPlugin` | History management | `rgs` |
|
|
19
|
+
| `schemaPlugin` | Schema validation | `rgs` |
|
|
20
|
+
| `guardPlugin` | Pre-set value transformation | `rgs` |
|
|
21
|
+
| `analyticsPlugin` | Track state changes | `rgs` |
|
|
22
|
+
|
|
23
|
+
## 🔎 1. DevTools: See Under the Hood
|
|
24
|
+
|
|
25
|
+
Import the official plugin and you'll see every state change, transaction, and execution time in the console or dev tools (Redux DevTools support included!).
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { devToolsPlugin } from '@biglogic/rgs';
|
|
29
|
+
|
|
30
|
+
store._addPlugin(devToolsPlugin({ name: 'My Store' }));
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 🐛 2. Debug: Console Access (DEV ONLY)
|
|
34
|
+
|
|
35
|
+
⚠️ **FOR DEVELOPMENT ONLY** - This plugin is automatically disabled in production.
|
|
36
|
+
|
|
37
|
+
Access your store directly from the browser console:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { debugPlugin } from '@biglogic/rgs';
|
|
41
|
+
|
|
42
|
+
// Always wrap in dev check
|
|
43
|
+
if (process.env.NODE_ENV === 'development') {
|
|
44
|
+
store._addPlugin(debugPlugin())
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Then in the browser console:
|
|
49
|
+
```javascript
|
|
50
|
+
gstate.list() // View all state
|
|
51
|
+
gstate.get('key') // Get a value
|
|
52
|
+
gstate.set('key', val) // Set a value
|
|
53
|
+
gstate.info() // Store info
|
|
54
|
+
gstate.banner() // Show help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 2. Cross-Tab Sync: Multi-Tab Magic
|
|
58
|
+
|
|
59
|
+
Have your app open in three browser tabs? With the `syncPlugin`, if a user changes the theme in one tab, all other tabs update instantly. **Without hitting the server.**
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { syncPlugin } from 'rgs/advanced';
|
|
63
|
+
|
|
64
|
+
store._addPlugin(syncPlugin({ channelName: 'my_app_sync' }));
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 🔐 3. Encode Option: Base64 Encoding
|
|
68
|
+
|
|
69
|
+
Use the `encoded` option for simple base64 encoding (not encryption, just obfuscation):
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Per-value encoding
|
|
73
|
+
store.set('token', 'secret-value', { persist: true, encoded: true })
|
|
74
|
+
|
|
75
|
+
// Or global encoding for all persisted values
|
|
76
|
+
const store = initState({ encoded: true })
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> **Note:** Use `encryptionKey` with AES-256-GCM for real security. The `encoded` option is just simple obfuscation.
|
|
80
|
+
|
|
81
|
+
## 🕐 4. TTL (Time To Live): Expiring Data
|
|
82
|
+
|
|
83
|
+
Use the `ttl` option in persist to make data expire automatically:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
store.set('session_token', tokenValue, {
|
|
87
|
+
persist: true,
|
|
88
|
+
ttl: 3600000 // Expires in 1 hour
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 🎲 5. Undo/Redo: History Management
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { undoRedoPlugin } from '@biglogic/rgs';
|
|
96
|
+
|
|
97
|
+
store._addPlugin(undoRedoPlugin({ limit: 50 }));
|
|
98
|
+
|
|
99
|
+
// Later...
|
|
100
|
+
store.undo();
|
|
101
|
+
store.redo();
|
|
102
|
+
store.canUndo(); // boolean
|
|
103
|
+
store.canRedo(); // boolean
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 📸 6. Snapshots: Save & Restore State
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { snapshotPlugin } from '@biglogic/rgs';
|
|
110
|
+
|
|
111
|
+
store._addPlugin(snapshotPlugin());
|
|
112
|
+
|
|
113
|
+
// Save current state
|
|
114
|
+
store.takeSnapshot('backup_1');
|
|
115
|
+
|
|
116
|
+
// Restore
|
|
117
|
+
store.restoreSnapshot('backup_1');
|
|
118
|
+
|
|
119
|
+
// List all snapshots
|
|
120
|
+
store.listSnapshots(); // ['backup_1', ...]
|
|
121
|
+
|
|
122
|
+
// Delete
|
|
123
|
+
store.deleteSnapshot('backup_1');
|
|
124
|
+
store.clearSnapshots();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## 🛡️ 7. Guard: Pre-Set Transformation
|
|
128
|
+
|
|
129
|
+
Transform values before they hit the store:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { guardPlugin } from '@biglogic/rgs';
|
|
133
|
+
|
|
134
|
+
store._addPlugin(guardPlugin({
|
|
135
|
+
'user_input': (val) => val.trim().toLowerCase()
|
|
136
|
+
}));
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## ✅ 8. Schema: Validation
|
|
140
|
+
|
|
141
|
+
Validate values before setting:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { schemaPlugin } from '@biglogic/rgs';
|
|
145
|
+
|
|
146
|
+
store._addPlugin(schemaPlugin({
|
|
147
|
+
'email': (val) => {
|
|
148
|
+
if (typeof val !== 'string') return 'Must be a string';
|
|
149
|
+
return val.includes('@') ? true : 'Invalid email';
|
|
150
|
+
}
|
|
151
|
+
}));
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 📊 9. Analytics: Track Changes
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { analyticsPlugin } from '@biglogic/rgs';
|
|
158
|
+
|
|
159
|
+
store._addPlugin(analyticsPlugin({
|
|
160
|
+
provider: (event) => {
|
|
161
|
+
console.log('State changed:', event);
|
|
162
|
+
// Send to analytics service
|
|
163
|
+
},
|
|
164
|
+
keys: ['user', 'cart'] // Only track these keys
|
|
165
|
+
}));
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 🔄 10. Immer Integration
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { immerPlugin } from '@biglogic/rgs';
|
|
172
|
+
|
|
173
|
+
store._addPlugin(immerPlugin());
|
|
174
|
+
|
|
175
|
+
// Update nested state with Immer
|
|
176
|
+
store.setWithProduce('user', (draft) => {
|
|
177
|
+
draft.name = 'New Name';
|
|
178
|
+
draft.address.city = 'New City';
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 💡 A Word of Wisdom for Easy & Advanced Scenarios
|
|
185
|
+
|
|
186
|
+
Plugins are used to **abstract the boring logic**. If you find yourself writing the same `useEffect` to sync two things in 5 different parts of your app... **Stop.** Create a plugin or use an existing one.
|
|
187
|
+
|
|
188
|
+
The best code is the code you write once and forget about.
|
|
189
|
+
|
|
190
|
+
**Next step:** [Case Studies: Real-World Production Strategies](06-case-studies.md)
|