@biglogic/rgs 3.7.0 β 3.7.2
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/README.md +84 -3
- package/package.json +105 -85
- package/COPYRIGHT.md +0 -4
- package/FUNDING.yml +0 -12
- package/SECURITY.md +0 -13
- package/advanced.d.ts +0 -9
- package/core/advanced.d.ts +0 -5
- package/core/async.d.ts +0 -8
- package/core/hooks.d.ts +0 -17
- package/core/persistence.d.ts +0 -23
- package/core/plugins.d.ts +0 -8
- package/core/reactivity.d.ts +0 -19
- package/core/security.d.ts +0 -56
- package/core/store.d.ts +0 -7
- package/core/sync.d.ts +0 -76
- package/core/types.d.ts +0 -163
- package/core/utils.d.ts +0 -2
- package/docs/README.md +0 -389
- package/docs/SUMMARY.md +0 -64
- package/docs/_config.yml +0 -1
- package/docs/api.md +0 -381
- package/docs/chapters/01-philosophy.md +0 -54
- package/docs/chapters/02-getting-started.md +0 -68
- package/docs/chapters/03-the-magnetar-way.md +0 -69
- package/docs/chapters/04-persistence-and-safety.md +0 -125
- package/docs/chapters/05-plugin-sdk.md +0 -290
- package/docs/chapters/05-plugins-and-extensibility.md +0 -190
- package/docs/chapters/06-case-studies.md +0 -69
- package/docs/chapters/07-faq.md +0 -53
- package/docs/chapters/08-migration-guide.md +0 -284
- package/docs/chapters/09-security-architecture.md +0 -50
- package/docs/chapters/10-local-first-sync.md +0 -146
- package/docs/qa.md +0 -47
- package/index.d.ts +0 -41
- package/index.js +0 -2
- package/index.js.map +0 -7
- package/plugins/index.d.ts +0 -15
- package/plugins/official/analytics.plugin.d.ts +0 -9
- package/plugins/official/cloud-sync.plugin.d.ts +0 -22
- package/plugins/official/debug.plugin.d.ts +0 -2
- package/plugins/official/devtools.plugin.d.ts +0 -4
- package/plugins/official/guard.plugin.d.ts +0 -2
- package/plugins/official/immer.plugin.d.ts +0 -2
- package/plugins/official/indexeddb.plugin.d.ts +0 -7
- package/plugins/official/schema.plugin.d.ts +0 -2
- package/plugins/official/snapshot.plugin.d.ts +0 -2
- package/plugins/official/sync.plugin.d.ts +0 -4
- package/plugins/official/undo-redo.plugin.d.ts +0 -4
- package/rgs-extension.vsix +0 -0
package/core/types.d.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import type { EncryptionKey, AuditEntry, Permission, AccessRule } from './security';
|
|
2
|
-
import type { SyncConfig } from './sync';
|
|
3
|
-
export interface PersistOptions {
|
|
4
|
-
persist?: boolean;
|
|
5
|
-
encoded?: boolean;
|
|
6
|
-
encrypted?: boolean;
|
|
7
|
-
ttl?: number;
|
|
8
|
-
}
|
|
9
|
-
export interface StoreMetadata {
|
|
10
|
-
version: number;
|
|
11
|
-
lastUpdated: number;
|
|
12
|
-
}
|
|
13
|
-
export type StoreSubscriber = () => void;
|
|
14
|
-
export type Middleware<T = unknown> = (key: string, value: T, meta: StoreMetadata) => void;
|
|
15
|
-
export type StateUpdater<T> = (draft: T) => void | T;
|
|
16
|
-
export type ComputedSelector<T> = (get: <V>(key: string) => V | null) => T;
|
|
17
|
-
export type WatcherCallback<T> = (value: T | null) => void;
|
|
18
|
-
export interface PluginMethod<T = unknown> {
|
|
19
|
-
(...args: unknown[]): T;
|
|
20
|
-
}
|
|
21
|
-
export type PluginMethods<T extends Record<string, PluginMethod>> = T;
|
|
22
|
-
export type PluginHookName = 'onInit' | 'onInstall' | 'onSet' | 'onGet' | 'onRemove' | 'onDestroy' | 'onTransaction' | 'onBeforeSet' | 'onAfterSet';
|
|
23
|
-
export interface PluginContext<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
24
|
-
store: IStore<S>;
|
|
25
|
-
key?: string;
|
|
26
|
-
value?: unknown;
|
|
27
|
-
version?: number;
|
|
28
|
-
}
|
|
29
|
-
export interface IPlugin<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
30
|
-
name: string;
|
|
31
|
-
hooks: {
|
|
32
|
-
[K in PluginHookName]?: (context: PluginContext<S>) => void | Promise<void>;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export declare const createTypedPlugin: <T extends Record<string, PluginMethod>>(name: string, methods: T) => IPlugin & {
|
|
36
|
-
methods: T;
|
|
37
|
-
};
|
|
38
|
-
export interface IStore<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
39
|
-
set<K extends keyof S>(key: K, valOrUp: S[K] | StateUpdater<S[K]>, options?: PersistOptions): boolean;
|
|
40
|
-
get<K extends keyof S>(key: K): S[K] | null;
|
|
41
|
-
set<T = unknown>(key: string, valOrUp: T | StateUpdater<T>, options?: PersistOptions): boolean;
|
|
42
|
-
get<T = unknown>(key: string): T | null;
|
|
43
|
-
compute<T = unknown>(key: string, selector: ComputedSelector<T>): T;
|
|
44
|
-
watch<K extends keyof S>(key: K, callback: WatcherCallback<S[K]>): () => void;
|
|
45
|
-
watch<T = unknown>(key: string, callback: WatcherCallback<T>): () => void;
|
|
46
|
-
remove(key: keyof S | string): boolean;
|
|
47
|
-
delete(key: keyof S | string): boolean;
|
|
48
|
-
deleteAll(): boolean;
|
|
49
|
-
list(): Record<string, unknown>;
|
|
50
|
-
use(m: Middleware): void;
|
|
51
|
-
transaction(fn: () => void): void;
|
|
52
|
-
destroy(): void;
|
|
53
|
-
_addPlugin(plugin: IPlugin<S>): void;
|
|
54
|
-
_removePlugin(name: string): void;
|
|
55
|
-
_subscribe(cb: StoreSubscriber, key?: string): () => void;
|
|
56
|
-
_getVersion(key: string): number;
|
|
57
|
-
_setSilently(key: string, value: unknown): void;
|
|
58
|
-
_registerMethod(pluginName: string, methodName: string, fn: (...args: unknown[]) => unknown): void;
|
|
59
|
-
getSnapshot(): S;
|
|
60
|
-
addAccessRule(pattern: string | ((key: string, userId?: string) => boolean), permissions: Permission[]): void;
|
|
61
|
-
hasPermission(key: string, action: Permission, userId?: string): boolean;
|
|
62
|
-
recordConsent(userId: string, purpose: string, granted: boolean): import('./security').ConsentRecord;
|
|
63
|
-
hasConsent(userId: string, purpose: string): boolean;
|
|
64
|
-
getConsents(userId: string): import('./security').ConsentRecord[];
|
|
65
|
-
revokeConsent(userId: string, purpose: string): import('./security').ConsentRecord | null;
|
|
66
|
-
exportUserData(userId: string): {
|
|
67
|
-
userId: string;
|
|
68
|
-
exportedAt: number;
|
|
69
|
-
consents: import('./security').ConsentRecord[];
|
|
70
|
-
};
|
|
71
|
-
deleteUserData(userId: string): {
|
|
72
|
-
success: boolean;
|
|
73
|
-
deletedConsents: number;
|
|
74
|
-
};
|
|
75
|
-
readonly isReady: boolean;
|
|
76
|
-
readonly namespace: string;
|
|
77
|
-
readonly userId?: string;
|
|
78
|
-
whenReady(): Promise<void>;
|
|
79
|
-
readonly plugins: GStatePlugins;
|
|
80
|
-
}
|
|
81
|
-
export interface GStatePlugins {
|
|
82
|
-
security: {
|
|
83
|
-
addAccessRule: (pattern: string | ((key: string, userId?: string) => boolean), permissions: Permission[]) => void;
|
|
84
|
-
recordConsent: (userId: string, purpose: string, granted: boolean) => import('./security').ConsentRecord;
|
|
85
|
-
hasConsent: (userId: string, purpose: string) => boolean;
|
|
86
|
-
getConsents: (userId: string) => import('./security').ConsentRecord[];
|
|
87
|
-
revokeConsent: (userId: string, purpose: string) => import('./security').ConsentRecord | null;
|
|
88
|
-
exportUserData: (userId: string) => {
|
|
89
|
-
userId: string;
|
|
90
|
-
exportedAt: number;
|
|
91
|
-
consents: import('./security').ConsentRecord[];
|
|
92
|
-
};
|
|
93
|
-
deleteUserData: (userId: string) => {
|
|
94
|
-
success: boolean;
|
|
95
|
-
deletedConsents: number;
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
undoRedo: {
|
|
99
|
-
undo: () => boolean;
|
|
100
|
-
redo: () => boolean;
|
|
101
|
-
canUndo: () => boolean;
|
|
102
|
-
canRedo: () => boolean;
|
|
103
|
-
};
|
|
104
|
-
immer: {
|
|
105
|
-
setWithProduce: <T>(key: string, updater: (draft: T) => void) => boolean;
|
|
106
|
-
};
|
|
107
|
-
cloudSync: {
|
|
108
|
-
sync: () => Promise<{
|
|
109
|
-
status: string;
|
|
110
|
-
stats: import('../plugins/official/cloud-sync.plugin').SyncStats;
|
|
111
|
-
}>;
|
|
112
|
-
getStats: () => import('../plugins/official/cloud-sync.plugin').SyncStats;
|
|
113
|
-
};
|
|
114
|
-
sync: {
|
|
115
|
-
flush: () => Promise<import('../core/sync').SyncResult>;
|
|
116
|
-
getState: () => import('../core/sync').SyncState;
|
|
117
|
-
onStateChange: (callback: (state: import('../core/sync').SyncState) => void) => () => void;
|
|
118
|
-
};
|
|
119
|
-
logger: Record<string, never>;
|
|
120
|
-
[key: string]: unknown;
|
|
121
|
-
}
|
|
122
|
-
export interface StoreConfig<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
123
|
-
namespace?: string;
|
|
124
|
-
version?: number;
|
|
125
|
-
silent?: boolean;
|
|
126
|
-
debounceTime?: number;
|
|
127
|
-
storage?: CustomStorage | Storage;
|
|
128
|
-
migrate?: (oldState: Record<string, unknown>, oldVersion: number) => S;
|
|
129
|
-
persistByDefault?: boolean;
|
|
130
|
-
persistence?: boolean;
|
|
131
|
-
persist?: boolean;
|
|
132
|
-
onError?: (error: Error, context: {
|
|
133
|
-
operation: string;
|
|
134
|
-
key?: string;
|
|
135
|
-
}) => void;
|
|
136
|
-
maxObjectSize?: number;
|
|
137
|
-
maxTotalSize?: number;
|
|
138
|
-
encryptionKey?: EncryptionKey;
|
|
139
|
-
auditEnabled?: boolean;
|
|
140
|
-
userId?: string;
|
|
141
|
-
validateInput?: boolean;
|
|
142
|
-
encoded?: boolean;
|
|
143
|
-
accessRules?: Array<{
|
|
144
|
-
pattern: string | ((key: string, userId?: string) => boolean);
|
|
145
|
-
permissions: Permission[];
|
|
146
|
-
}>;
|
|
147
|
-
immer?: boolean;
|
|
148
|
-
sync?: SyncConfig;
|
|
149
|
-
}
|
|
150
|
-
export interface CustomStorage {
|
|
151
|
-
getItem(key: string): string | null;
|
|
152
|
-
setItem(key: string, value: string): void;
|
|
153
|
-
removeItem(key: string): void;
|
|
154
|
-
key(index: number): string | null;
|
|
155
|
-
length: number;
|
|
156
|
-
}
|
|
157
|
-
export interface AsyncState<T> {
|
|
158
|
-
data: T | null;
|
|
159
|
-
loading: boolean;
|
|
160
|
-
error: Error | null;
|
|
161
|
-
updatedAt: number | null;
|
|
162
|
-
}
|
|
163
|
-
export type { EncryptionKey, AuditEntry, Permission, AccessRule };
|
package/core/utils.d.ts
DELETED
package/docs/README.md
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
# Argis (RGS) - Reactive Global State
|
|
2
|
-
|
|
3
|
-
> "The Magnetar" **Atomic Precision. Immutable Safety. Zen Simplicity.**
|
|
4
|
-
> The most powerful state management engine for React. Built for those who demand industrial-grade reliability with a zero-boilerplate experience.
|
|
5
|
-
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
[](https://npmjs.org/package/@biglogic/rgs)
|
|
8
|
-
[](https://npmjs.org/package/@biglogic/rgs)
|
|
9
|
-
|
|
10
|
-

|
|
11
|
-

|
|
12
|
-

|
|
13
|
-

|
|
14
|
-

|
|
15
|
-

|
|
16
|
-

|
|
17
|
-

|
|
18
|
-
|
|
19
|
-

|
|
20
|
-

|
|
21
|
-
|
|
22
|
-
<!-- [](https://a51.gitbook.io/rgs) -->
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## π Why Magnetar?
|
|
27
|
-
|
|
28
|
-
We took the simplicity of **Reactive Global State (RGS)** and fused it with the architecture of a **High-Performance Kernel**. It's the only library that gives you:
|
|
29
|
-
|
|
30
|
-
- **π Absolute Immutability**: Powered by **Immer**. No more manual spreads. State is frozen by default.
|
|
31
|
-
- **π‘οΈ Industrial-Grade Safety**: Deep Proxy guards that throw `Forbidden Mutation` errors if you try to bypass the kernel.
|
|
32
|
-
- **π Enterprise Ecosystem**: A real plugin architecture with 10+ official modules (Sync, Storage, DevTools, etc.).
|
|
33
|
-
- **βοΈ Power on Demand**: Advanced async and persistence tools isolated in the `advanced` export.
|
|
34
|
-
- **ποΈ Stellar Architecture**: Zero circular dependencies. Modular, clean, and 100% type-safe.
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## gState vs useState
|
|
39
|
-
|
|
40
|
-
| Feature | RGS gState | React useState |
|
|
41
|
-
|---------|--------|----------|
|
|
42
|
-
| **Global state across components** | β
Automatic sharing | β Need Context/props |
|
|
43
|
-
| **Provider wrapper** | β
Not needed | β Required |
|
|
44
|
-
| **Persistence (localStorage)** | β
Built-in | β Manual |
|
|
45
|
-
| **Data encryption** | β
AES-256-GCM | β |
|
|
46
|
-
| **Multiple namespaces/stores** | β
| β |
|
|
47
|
-
| **Plugins (Immer, Undo/Redo)** | β
| β |
|
|
48
|
-
| **Audit logging** | β
| β |
|
|
49
|
-
| **RBAC/GDPR consent** | β
| β |
|
|
50
|
-
| **SSR/Hydration** | β
Automatic | β Manual |
|
|
51
|
-
| **Computed values** | β
| β |
|
|
52
|
-
|
|
53
|
-
### When to use what?
|
|
54
|
-
|
|
55
|
-
- **useState**: Local UI, single component, temporary state
|
|
56
|
-
- **gState**:
|
|
57
|
-
- Shared state across multiple components
|
|
58
|
-
- Persistent data (preferences, cart, authentication)
|
|
59
|
-
- Sensitive data (encryption)
|
|
60
|
-
- Advanced features (undo/redo, snapshots)
|
|
61
|
-
- Enterprise (audit, RBAC, GDPR)
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## βοΈ The Arena: RGS vs The World
|
|
66
|
-
|
|
67
|
-
|Feature|**RGS (Argis)**|Zustand|Redux Toolkit|Recoil|
|
|
68
|
-
|:---|:---|:---|:---|:---|
|
|
69
|
-
| **Philosophy** | **Zen State** | Minimalist | Enterprise Flux | Atomic |
|
|
70
|
-
| **API Surface** | **1 Function** | Simple | Complex | Complex |
|
|
71
|
-
| **Mutations** | **Magic (Immer)** | Manual Spreads | Magic (Immer) | Manual |
|
|
72
|
-
| **Selectors** | β
**Type-Safe** | β
Functional | β
Functional | β οΈ Selectors |
|
|
73
|
-
| **Security** | π‘οΈ **AES-256 + RBAC** | β None | β Ecosystem | β None |
|
|
74
|
-
| **Persistence** | πΎ **First-class** | π Middleware | π Middleware | π Effects |
|
|
75
|
-
| **Async** | β
**Atomic** | β
Async/Await | β
Thunks | β
Suspense |
|
|
76
|
-
| **Local-First Sync** | β
**Built-in** | β None | β None | β None |
|
|
77
|
-
| **Bundle Size** | **~2kB** | ~1kB | >10kB | >20kB |
|
|
78
|
-
|
|
79
|
-
> **RGS** is the only library on the market that treats **Security** and **Persistence** as first-class citizens.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
### Installation
|
|
84
|
-
|
|
85
|
-
```shell
|
|
86
|
-
npm install @biglogic/rgs
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
### Examples and guide
|
|
92
|
-
|
|
93
|
-
**[github.com/BigLogic-ca/rgs](https://github.com/BigLogic-ca/rgs)**
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## ποΈ Architecture
|
|
98
|
-
|
|
99
|
-
```mermaid
|
|
100
|
-
graph TB
|
|
101
|
-
subgraph API
|
|
102
|
-
A[gstate] --> D[IStore]
|
|
103
|
-
B[useStore] --> D
|
|
104
|
-
C[createStore] --> D
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
D --> E[Storage Adapter]
|
|
108
|
-
D --> F[Immer Proxy]
|
|
109
|
-
D --> G[Plugins]
|
|
110
|
-
D --> H[Security]
|
|
111
|
-
D --> I[Async Store]
|
|
112
|
-
|
|
113
|
-
E --> J[local]
|
|
114
|
-
E --> K[session]
|
|
115
|
-
E --> L[memory]
|
|
116
|
-
|
|
117
|
-
G --> M[UndoRedo]
|
|
118
|
-
G --> N[Sync]
|
|
119
|
-
G --> O[Schema]
|
|
120
|
-
G --> P[Analytics]
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Core Components
|
|
124
|
-
|
|
125
|
-
| Component | Description |
|
|
126
|
-
|-----------|-------------|
|
|
127
|
-
| **gstate()** | Creates store + hook in one line |
|
|
128
|
-
| **useStore()** | React hook for subscribing to state |
|
|
129
|
-
| **createStore()** | Classic store factory |
|
|
130
|
-
| **IStore** | Core interface with get/set/subscribe |
|
|
131
|
-
| **StorageAdapters** | local, session, memory persistence |
|
|
132
|
-
| **Plugins** | Immer, Undo/Redo, Sync, Schema, etc. |
|
|
133
|
-
| **Security** | Encryption, RBAC, GDPR consent |
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Requirements
|
|
138
|
-
|
|
139
|
-
- **React 16.8+** (for hooks support)
|
|
140
|
-
- **React DOM**
|
|
141
|
-
|
|
142
|
-
## β‘ Zero-Boilerplate Quickstart
|
|
143
|
-
|
|
144
|
-
### Path A: The Zen Way (Modular)
|
|
145
|
-
|
|
146
|
-
Best for modern applications. Clean imports, zero global pollution, **Type-Safe**.
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
import { gstate } from '@biglogic/rgs'
|
|
150
|
-
|
|
151
|
-
// 1. Create a typed store hook
|
|
152
|
-
const useCounter = gstate({ count: 0, user: { name: 'Alice' } })
|
|
153
|
-
|
|
154
|
-
// 2. Use with Type-Safe Selectors (Preferred)
|
|
155
|
-
const count = useCounter(state => state.count)
|
|
156
|
-
const userName = useCounter(state => state.user.name)
|
|
157
|
-
|
|
158
|
-
// OR use string keys (Legacy)
|
|
159
|
-
const [count, setCount] = useCounter('count')
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Path B: The Classic Way (Global)
|
|
163
|
-
|
|
164
|
-
Best for shared state across the entire application.
|
|
165
|
-
|
|
166
|
-
```tsx
|
|
167
|
-
// 1. Initialize once
|
|
168
|
-
import { initState, useStore } from '@biglogic/rgs'
|
|
169
|
-
initState({ namespace: 'app' })
|
|
170
|
-
|
|
171
|
-
// 2. Use anywhere
|
|
172
|
-
const [user, setUser] = useStore('user')
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
|
-
## π‘οΈ Security Architecture
|
|
178
|
-
|
|
179
|
-
RGS includes enterprise-grade security features to protect your application and user data:
|
|
180
|
-
|
|
181
|
-
### ReDoS Protection
|
|
182
|
-
All regex patterns used in RBAC permission matching include timeout protection (100ms) to prevent Regex Denial of Service attacks.
|
|
183
|
-
|
|
184
|
-
### Safe UUID Generation
|
|
185
|
-
Falls back to cryptographically secure random UUID generation when native `crypto.randomUUID()` is unavailable.
|
|
186
|
-
|
|
187
|
-
### Input Validation
|
|
188
|
-
- **Storage Key Validation**: Keys are validated against `/^[a-zA-Z0-9_.-]+$/` to prevent injection attacks
|
|
189
|
-
- **Value Sanitization**: All persisted values are sanitized to prevent XSS attacks
|
|
190
|
-
|
|
191
|
-
### Encryption
|
|
192
|
-
- **AES-256-GCM**: Industry-standard encryption for sensitive data
|
|
193
|
-
- **Encoded Mode**: Use `{ encoded: true }` option for base64-encoded storage (note: renamed from `secure` for clarity)
|
|
194
|
-
|
|
195
|
-
### GDPR Compliance
|
|
196
|
-
- Consent management system
|
|
197
|
-
- Data export (`exportData()`)
|
|
198
|
-
- Data deletion (`deleteData()`)
|
|
199
|
-
|
|
200
|
-
### Development vs Production
|
|
201
|
-
Global `gstate` exposure to window is only enabled in development mode (`NODE_ENV !== 'production'`).
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## π Quick Examples
|
|
206
|
-
|
|
207
|
-
```tsx
|
|
208
|
-
const store = gstate({ theme: 'dark' }, "my-app")
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Encryption
|
|
212
|
-
|
|
213
|
-
```tsx
|
|
214
|
-
const secureStore = gstate({ token: 'xxx' }, { encoded: true })
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Undo/Redo
|
|
218
|
-
|
|
219
|
-
```tsx
|
|
220
|
-
const store = gstate({ count: 0 })
|
|
221
|
-
store._addPlugin(undoRedoPlugin({ limit: 50 }))
|
|
222
|
-
|
|
223
|
-
store.undo()
|
|
224
|
-
store.redo()
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Cross-Tab Sync
|
|
228
|
-
|
|
229
|
-
```tsx
|
|
230
|
-
const store = gstate({ theme: 'light' })
|
|
231
|
-
store._addPlugin(syncPlugin({ channelName: 'my-app' }))
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
```tsx
|
|
235
|
-
const store = gstate({ firstName: 'John', lastName: 'Doe' })
|
|
236
|
-
store.compute('fullName', (get) => `${get('firstName')} ${get('lastName')}`)
|
|
237
|
-
|
|
238
|
-
const [fullName] = store('fullName') // "John Doe"
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Error Handling with onError
|
|
242
|
-
|
|
243
|
-
Handle errors gracefully with the `onError` callback - perfect for production apps:
|
|
244
|
-
|
|
245
|
-
```tsx
|
|
246
|
-
const store = gstate({ data: null }, {
|
|
247
|
-
onError: (error, context) => {
|
|
248
|
-
console.error(`Error in ${context.operation}:`, error.message)
|
|
249
|
-
// Send to error tracking service (Sentry, etc.)
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Size Limits (maxObjectSize & maxTotalSize)
|
|
255
|
-
|
|
256
|
-
Protect your app from memory issues with automatic size warnings:
|
|
257
|
-
|
|
258
|
-
```tsx
|
|
259
|
-
const store = gstate({ data: {} }, {
|
|
260
|
-
// Warn if single value exceeds 5MB (Default is 0/Disabled for performance)
|
|
261
|
-
maxObjectSize: 5 * 1024 * 1024,
|
|
262
|
-
// Warn if total store exceeds 50MB (Default is 0/Disabled)
|
|
263
|
-
maxTotalSize: 50 * 1024 * 1024
|
|
264
|
-
})
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Local-First Sync (Offline-by-Default)
|
|
268
|
-
|
|
269
|
-
RGS now includes a powerful Local-First Sync Engine that makes your app work offline by default:
|
|
270
|
-
|
|
271
|
-
```tsx
|
|
272
|
-
import { gstate, useSyncedState } from '@biglogic/rgs'
|
|
273
|
-
|
|
274
|
-
// Create store with built-in sync
|
|
275
|
-
const store = gstate({
|
|
276
|
-
todos: [],
|
|
277
|
-
user: null
|
|
278
|
-
}, {
|
|
279
|
-
namespace: 'myapp',
|
|
280
|
-
sync: {
|
|
281
|
-
endpoint: 'https://api.example.com/sync',
|
|
282
|
-
// Use a getter function to avoid exposing token in memory
|
|
283
|
-
authToken: () => localStorage.getItem('auth_token'),
|
|
284
|
-
autoSyncInterval: 30000, // Sync every 30s
|
|
285
|
-
syncOnReconnect: true, // Auto-sync when back online
|
|
286
|
-
strategy: 'last-write-wins' // Conflict resolution
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
// Use in React - automatically synced!
|
|
291
|
-
function TodoList() {
|
|
292
|
-
const [todos, setTodos] = useSyncedState('todos')
|
|
293
|
-
|
|
294
|
-
// Works offline automatically
|
|
295
|
-
const addTodo = (text) => {
|
|
296
|
-
setTodos([...todos, { id: Date.now(), text }])
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return <div>{/* ... */}</div>
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
## Multiple Stores
|
|
306
|
-
|
|
307
|
-
You can create multiple independent stores using namespaces:
|
|
308
|
-
|
|
309
|
-
```tsx
|
|
310
|
-
// Option 1: gstate with namespace
|
|
311
|
-
const userStore = gstate({ name: 'John' }, { namespace: 'users' })
|
|
312
|
-
const appStore = gstate({ theme: 'dark' }, { namespace: 'app' })
|
|
313
|
-
|
|
314
|
-
// In components - same key, different stores
|
|
315
|
-
const [name] = userStore('name') // 'John'
|
|
316
|
-
const [theme] = appStore('theme') // 'dark'
|
|
317
|
-
|
|
318
|
-
// Option 2: initState + useStore (global default store)
|
|
319
|
-
initState({ namespace: 'global' })
|
|
320
|
-
const [value, setValue] = useStore('key')
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
**Tip**: Keys are unique per-namespace, so you can use the same key name in different stores.
|
|
324
|
-
|
|
325
|
-
## π Advanced Superpowers
|
|
326
|
-
|
|
327
|
-
### π Official Plugin Ecosystem
|
|
328
|
-
|
|
329
|
-
Extend the core functionality dynamically with specialized modules.
|
|
330
|
-
|
|
331
|
-
1. **ImmerPlugin**: Adds `setWithProduce` for functional updates.
|
|
332
|
-
2. **UndoRedoPlugin**: Multi-level history management.
|
|
333
|
-
3. **PersistencePlugin**: Advanced storage with custom serialization.
|
|
334
|
-
4. **SyncPlugin**: Cross-tab state synchronization via BroadcastChannel.
|
|
335
|
-
5. **SchemaPlugin**: Runtime validation (perfect for Zod).
|
|
336
|
-
6. **DevToolsPlugin**: Redux DevTools integration.
|
|
337
|
-
7. **TTLPlugin**: Time-to-live management.
|
|
338
|
-
8. **AnalyticsPlugin**: Tracking bridge for metrics.
|
|
339
|
-
9. **SnapshotPlugin**: Manual state checkpointing.
|
|
340
|
-
10. **GuardPlugin**: Data transformation layer.
|
|
341
|
-
11. **Local-First Sync**: Built-in offline-first with auto-sync (NEW!)
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
import { createStore, PersistencePlugin, undoRedoPlugin } from '@biglogic/rgs'
|
|
345
|
-
|
|
346
|
-
const store = createStore()
|
|
347
|
-
store._addPlugin(PersistencePlugin({ storage: 'localStorage' }))
|
|
348
|
-
store._addPlugin(undoRedoPlugin({ limit: 50 }))
|
|
349
|
-
|
|
350
|
-
// Undo like a pro
|
|
351
|
-
store.undo()
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### π¬ Power Tools (Import from `rgs/advanced`)
|
|
355
|
-
|
|
356
|
-
Need the heavy artillery? We've got you covered.
|
|
357
|
-
|
|
358
|
-
- `createAsyncStore(fetcher)`: Atomic async state management.
|
|
359
|
-
- `StorageAdapters`: High-level interfaces for any storage engine.
|
|
360
|
-
- `Middleware / IPlugin`: Build your own extensions.
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## π‘οΈ Quality & Testing
|
|
365
|
-
|
|
366
|
-
RGS is built with an obsession for reliability. Our test suite covers multiple layers to ensure zero-regressions:
|
|
367
|
-
|
|
368
|
-
- **Unit Tests (Jest)**: 100+ tests covering core logic, stores, and hooks.
|
|
369
|
-
- **E2E Tests (Playwright)**: Real-world browser testing for cross-tab synchronization and Web Crypto API.
|
|
370
|
-
- **Concurrency Testing**: Verification of race conditions in multi-tab environments.
|
|
371
|
-
|
|
372
|
-
```bash
|
|
373
|
-
# Run unit tests
|
|
374
|
-
npm run test
|
|
375
|
-
|
|
376
|
-
# Run E2E tests
|
|
377
|
-
npm run test:e2e
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
---
|
|
381
|
-
|
|
382
|
-
## π License
|
|
383
|
-
|
|
384
|
-
MIT Β© [Dario Passariello](https://github.com/dpassariello)
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
**Designed for those who build the future.**
|
|
389
|
-
Made with β€οΈ and a lot of caffe' espresso!
|
package/docs/SUMMARY.md
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# π Argis (RGS) - Reactive Global State: The Final Guide
|
|
2
|
-
|
|
3
|
-
Welcome to the definitive documentation for **Reactive Global State (RGS)**. If you are here, you're likely tired of endless boilerplate, complex configurations, and state management tools that seem to require a PhD in rocket science.
|
|
4
|
-
|
|
5
|
-
This documentation is written for everyone: from **easy setup** for those who just want things to work, to **advanced implementation** for those who want to master the engine.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## πΊοΈ Summary
|
|
10
|
-
|
|
11
|
-
- **[The Philosophy: Panzer vs. Bicycle](chapters/01-philosophy.md)**
|
|
12
|
-
- Reliability and Security as First-Class Citizens.
|
|
13
|
-
- The "Ironclad" Core: Simplicity meets Power.
|
|
14
|
-
|
|
15
|
-
- **[Quick Start: 30-Second Setup](chapters/02-getting-started.md)**
|
|
16
|
-
- Deploying the RGS Panzer in your React project.
|
|
17
|
-
|
|
18
|
-
- **[The Magnetar Way: One-Liner Power](chapters/03-the-magnetar-way.md)**
|
|
19
|
-
- Creating stores and hooks simultaneously. Types included.
|
|
20
|
-
|
|
21
|
-
- **[Persistence and Safety](chapters/04-persistence-and-safety.md)**
|
|
22
|
-
- Never lose user data again (without localStorage headaches).
|
|
23
|
-
- Native immutability with Immer (Stellar Engine).
|
|
24
|
-
|
|
25
|
-
- **[Ecosystem and Plugins](chapters/05-plugins-and-extensibility.md)**
|
|
26
|
-
- DevTools, Cross-Tab Sync, Analytics, and Typed Plugins.
|
|
27
|
-
|
|
28
|
-
- **[Plugin SDK: Build Your Own Extensions](chapters/05-plugin-sdk.md)**
|
|
29
|
-
- Create custom plugins with lifecycle hooks.
|
|
30
|
-
- Register methods via `store.plugins`.
|
|
31
|
-
- Full API reference and examples.
|
|
32
|
-
|
|
33
|
-
- **[Case Studies: Real World Strategies](chapters/06-case-studies.md)**
|
|
34
|
-
- **E-commerce**: Cart isolation and atomic updates.
|
|
35
|
-
- **Dashboards**: Multi-store strategies and complex flows.
|
|
36
|
-
|
|
37
|
-
- **[Architectural Insights (FAQ)](chapters/07-faq.md)**
|
|
38
|
-
- Honest answers on security, performance, and Proxies.
|
|
39
|
-
|
|
40
|
-
- **[Migration Guide](chapters/08-migration-guide.md)**
|
|
41
|
-
- Upgrading to latest version (Enterprise Isolation)
|
|
42
|
-
- Upgrading to previous version (`secure` β `encoded`)
|
|
43
|
-
|
|
44
|
-
- **[Security Architecture & Hardening](chapters/09-security-architecture.md)**
|
|
45
|
-
- Advanced XSS prevention and deep cloning reliability.
|
|
46
|
-
- AES-256-GCM and RBAC.
|
|
47
|
-
|
|
48
|
-
- **[Local-First Sync Engine](chapters/10-local-first-sync.md)**
|
|
49
|
-
- Offline-by-default with automatic background sync.
|
|
50
|
-
- Conflict resolution strategies (last-write-wins, merge, etc.).
|
|
51
|
-
- `useSyncedState` hook for React components.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Reference
|
|
56
|
-
|
|
57
|
-
- **[API Reference](api.md)**
|
|
58
|
-
- Complete API documentation
|
|
59
|
-
- Type definitions
|
|
60
|
-
- Plugin hooks
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
> *"Make things simple, but not simpler than necessary."* β RGS Team
|
package/docs/_config.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
theme: jekyll-theme-modernist
|