@biglogic/rgs 2.7.0
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/dist/CODEOWNERS +1 -0
- package/dist/CONTRIBUTING.md +65 -0
- package/dist/COPYRIGHT.md +4 -0
- package/dist/LICENSE +9 -0
- package/dist/README.md +267 -0
- package/dist/SECURITY.md +3 -0
- package/dist/advanced.d.ts +9 -0
- package/dist/advanced.js +1 -0
- package/dist/core/advanced.d.ts +5 -0
- package/dist/core/async.d.ts +8 -0
- package/dist/core/hooks.d.ts +8 -0
- package/dist/core/security.d.ts +54 -0
- package/dist/core/store.d.ts +7 -0
- package/dist/core/types.d.ts +134 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +1 -0
- package/dist/markdown/SUMMARY.md +55 -0
- package/dist/markdown/api.md +342 -0
- package/dist/markdown/chapters/01-philosophy.md +54 -0
- package/dist/markdown/chapters/02-getting-started.md +68 -0
- package/dist/markdown/chapters/03-the-magnetar-way.md +62 -0
- package/dist/markdown/chapters/04-persistence-and-safety.md +84 -0
- package/dist/markdown/chapters/05-plugin-sdk.md +290 -0
- package/dist/markdown/chapters/05-plugins-and-extensibility.md +174 -0
- package/dist/markdown/chapters/06-case-studies.md +69 -0
- package/dist/markdown/chapters/07-faq.md +53 -0
- package/dist/markdown/chapters/08-migration-guide.md +206 -0
- package/dist/package.json +81 -0
- package/dist/plugins/index.d.ts +13 -0
- package/dist/plugins/official/analytics.plugin.d.ts +9 -0
- package/dist/plugins/official/debug.plugin.d.ts +2 -0
- package/dist/plugins/official/devtools.plugin.d.ts +4 -0
- package/dist/plugins/official/guard.plugin.d.ts +2 -0
- package/dist/plugins/official/immer.plugin.d.ts +2 -0
- package/dist/plugins/official/schema.plugin.d.ts +2 -0
- package/dist/plugins/official/snapshot.plugin.d.ts +2 -0
- package/dist/plugins/official/sync.plugin.d.ts +4 -0
- package/dist/plugins/official/undo-redo.plugin.d.ts +4 -0
- package/package.json +81 -0
package/dist/CODEOWNERS
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @passariello
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Contributing to RGS (Argis) - React Globo State
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Clone the repository
|
|
9
|
+
git clone https://github.com/dpassariello/rgs.git
|
|
10
|
+
cd rgs
|
|
11
|
+
|
|
12
|
+
# Install dependencies
|
|
13
|
+
npm install
|
|
14
|
+
|
|
15
|
+
# Run tests
|
|
16
|
+
npm test
|
|
17
|
+
|
|
18
|
+
# Run linter
|
|
19
|
+
npm run lint
|
|
20
|
+
|
|
21
|
+
# Build
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Code Style
|
|
26
|
+
|
|
27
|
+
- Use TypeScript with strict mode
|
|
28
|
+
- Follow ESLint rules
|
|
29
|
+
- Add JSDoc comments for public APIs
|
|
30
|
+
- Write tests for new features
|
|
31
|
+
|
|
32
|
+
## Testing
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Run all tests
|
|
36
|
+
npm test
|
|
37
|
+
|
|
38
|
+
# Run tests in watch mode
|
|
39
|
+
npm run test:watch
|
|
40
|
+
|
|
41
|
+
# Run e2e tests
|
|
42
|
+
npm run test:e2e
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Pull Request Process
|
|
46
|
+
|
|
47
|
+
1. Fork the repository
|
|
48
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
49
|
+
3. Make your changes
|
|
50
|
+
4. Ensure tests pass: `npm test`
|
|
51
|
+
5. Ensure linting passes: `npm run lint`
|
|
52
|
+
6. Commit your changes
|
|
53
|
+
7. Push to your fork
|
|
54
|
+
8. Open a Pull Request
|
|
55
|
+
|
|
56
|
+
## Release Process
|
|
57
|
+
|
|
58
|
+
1. Update version in `package.json`
|
|
59
|
+
2. Update CHANGELOG.md
|
|
60
|
+
3. Create a release on GitHub
|
|
61
|
+
4. NPM publish happens automatically via CI/CD
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
package/dist/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# MIT license
|
|
2
|
+
|
|
3
|
+
Copyright 1995 - 2026 Dario Passariello
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Argis (RGS) - React Globo State "The Magnetar"
|
|
2
|
+
|
|
3
|
+
> **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://badge.fury.io/js/rgs)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🌟 Why Magnetar?
|
|
12
|
+
|
|
13
|
+
We took the simplicity of **React Globo State (RGS)** and fused it with the architecture of a **High-Performance Kernel**. It's the only library that gives you:
|
|
14
|
+
|
|
15
|
+
- **💎 Absolute Immutability**: Powered by **Immer**. No more manual spreads. State is frozen by default.
|
|
16
|
+
- **🛡️ Industrial-Grade Safety**: Deep Proxy guards that throw `Forbidden Mutation` errors if you try to bypass the kernel.
|
|
17
|
+
- **🔌 Enterprise Ecosystem**: A real plugin architecture with 10+ official modules (Sync, Storage, DevTools, etc.).
|
|
18
|
+
- **⚛️ Power on Demand**: Advanced async and persistence tools isolated in the `advanced` export.
|
|
19
|
+
- **🏗️ Stellar Architecture**: Zero circular dependencies. Modular, clean, and 100% type-safe.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## gState vs useState
|
|
24
|
+
|
|
25
|
+
| Feature | useState | gState |
|
|
26
|
+
|---------|----------|--------|
|
|
27
|
+
| **State globale tra componenti** | ❌ Servono Context/props | ✅ Condivisione automatica |
|
|
28
|
+
| **Provider wrapper** | ❌ Necessario | ✅ Non serve |
|
|
29
|
+
| **Persistenza (localStorage)** | ❌ Manuale | ✅ Built-in |
|
|
30
|
+
| **Crittografia dati** | ❌ | ✅ AES-256-GCM |
|
|
31
|
+
| **Namespace/stores multipli** | ❌ | ✅ |
|
|
32
|
+
| **Plugin (Immer, Undo/Redo)** | ❌ | ✅ |
|
|
33
|
+
| **Audit logging** | ❌ | ✅ |
|
|
34
|
+
| **RBAC/GDPR consent** | ❌ | ✅ |
|
|
35
|
+
| **SSR/Hydration** | ❌ Manuale | ✅ Automatico |
|
|
36
|
+
| **Computed values** | ❌ | ✅ |
|
|
37
|
+
|
|
38
|
+
### Quando usare cosa?
|
|
39
|
+
|
|
40
|
+
- **useState**: UI locale, un componente, state temporaneo
|
|
41
|
+
- **gState**:
|
|
42
|
+
- State condiviso tra più componenti
|
|
43
|
+
- Dati persistenti (preferenze, carrello, autenticazione)
|
|
44
|
+
- Dati sensibili (crittografia)
|
|
45
|
+
- Feature advanced (undo/redo, snapshots)
|
|
46
|
+
- Enterprise (audit, RBAC, GDPR)
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🏗️ Architecture
|
|
51
|
+
|
|
52
|
+
```mermaid
|
|
53
|
+
graph TB
|
|
54
|
+
subgraph API
|
|
55
|
+
A[gstate] --> D[IStore]
|
|
56
|
+
B[useStore] --> D
|
|
57
|
+
C[createStore] --> D
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
D --> E[Storage Adapter]
|
|
61
|
+
D --> F[Immer Proxy]
|
|
62
|
+
D --> G[Plugins]
|
|
63
|
+
D --> H[Security]
|
|
64
|
+
D --> I[Async Store]
|
|
65
|
+
|
|
66
|
+
E --> J[local]
|
|
67
|
+
E --> K[session]
|
|
68
|
+
E --> L[memory]
|
|
69
|
+
|
|
70
|
+
G --> M[UndoRedo]
|
|
71
|
+
G --> N[Sync]
|
|
72
|
+
G --> O[Schema]
|
|
73
|
+
G --> P[Analytics]
|
|
74
|
+
```
|
|
75
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
76
|
+
│ React Globo State │
|
|
77
|
+
│ "The Magnetar" │
|
|
78
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
79
|
+
│
|
|
80
|
+
┌─────────────────────┼─────────────────────┐
|
|
81
|
+
▼ ▼ ▼
|
|
82
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
83
|
+
│ gstate() │ │ useStore() │ │ createStore() │
|
|
84
|
+
│ (One-liner) │ │ (Hook) │ │ (Classic) │
|
|
85
|
+
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
|
86
|
+
│ │ │
|
|
87
|
+
└────────────────────┼────────────────────┘
|
|
88
|
+
▼
|
|
89
|
+
┌────────────────┐
|
|
90
|
+
│ IStore │
|
|
91
|
+
│ (Core API) │
|
|
92
|
+
└────────┬───────┘
|
|
93
|
+
│
|
|
94
|
+
┌──────────┬───────────┼───────────┬──────────┐
|
|
95
|
+
▼ ▼ ▼ ▼ ▼
|
|
96
|
+
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌─────────┐
|
|
97
|
+
│ Storage │ │Immer │ │ Plugins │ │Security│ │ Async │
|
|
98
|
+
│Adapter │ │Proxy │ │ System │ │ Layer │ │ Store │
|
|
99
|
+
└────┬────┘ └────┬────┘ └────┬─────┘ └───┬────┘ └───┬────┘
|
|
100
|
+
│ │ │ │ │
|
|
101
|
+
▼ ▼ ▼ ▼ ▼
|
|
102
|
+
local ┌─────────┐ ┌──────┐ ┌─────────┐ ┌──────┐
|
|
103
|
+
session │Frozen │ │Add │ │AES-256 │ │Fetch │
|
|
104
|
+
memory │State │ │Hooks │ │Encryption│ │+Loading│
|
|
105
|
+
└─────────┘ └──────┘ └─────────┘ │Error │
|
|
106
|
+
└──────┘
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Core Components
|
|
110
|
+
|
|
111
|
+
| Component | Description |
|
|
112
|
+
|-----------|-------------|
|
|
113
|
+
| **gstate()** | Creates store + hook in one line |
|
|
114
|
+
| **useStore()** | React hook for subscribing to state |
|
|
115
|
+
| **createStore()** | Classic store factory |
|
|
116
|
+
| **IStore** | Core interface with get/set/subscribe |
|
|
117
|
+
| **StorageAdapters** | local, session, memory persistence |
|
|
118
|
+
| **Plugins** | Immer, Undo/Redo, Sync, Schema, etc. |
|
|
119
|
+
| **Security** | Encryption, RBAC, GDPR consent |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Requirements
|
|
124
|
+
|
|
125
|
+
- **React 16.8+** (for hooks support)
|
|
126
|
+
- **React DOM**
|
|
127
|
+
|
|
128
|
+
## ⚡ Zero-Boilerplate Quickstart
|
|
129
|
+
|
|
130
|
+
### Path A: The Zen Way (Modular)
|
|
131
|
+
|
|
132
|
+
Best for modern applications. Clean imports, zero global pollution.
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { gstate } from 'argis'
|
|
136
|
+
|
|
137
|
+
// Create store and hook in one line
|
|
138
|
+
const useCounter = gstate({ count: 0 })
|
|
139
|
+
|
|
140
|
+
// In your component
|
|
141
|
+
const [count, setCount] = useCounter('count')
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Path B: The Classic Way (Global)
|
|
145
|
+
|
|
146
|
+
Best for shared state across the entire application.
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
// 1. Initialize once
|
|
150
|
+
import { initState } from 'argis'
|
|
151
|
+
initState({ namespace: 'app' })
|
|
152
|
+
|
|
153
|
+
// 2. Use anywhere
|
|
154
|
+
const [user, setUser] = useStore('user')
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 📚 Quick Examples
|
|
160
|
+
|
|
161
|
+
### Persistence
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
const store = gstate({ theme: 'dark' }, { persist: true })
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Encryption
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
const secureStore = gstate({ token: 'xxx' }, { encoded: true })
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Undo/Redo
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
const store = gstate({ count: 0 })
|
|
177
|
+
store._addPlugin(undoRedoPlugin({ limit: 50 }))
|
|
178
|
+
|
|
179
|
+
store.undo()
|
|
180
|
+
store.redo()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Cross-Tab Sync
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
const store = gstate({ theme: 'light' })
|
|
187
|
+
store._addPlugin(syncPlugin({ channelName: 'my-app' }))
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Computed Values
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
const store = gstate({ firstName: 'John', lastName: 'Doe' })
|
|
194
|
+
store.compute('fullName', ['firstName', 'lastName'],
|
|
195
|
+
(s) => `${s.firstName} ${s.lastName}`)
|
|
196
|
+
|
|
197
|
+
const [fullName] = store('fullName') // "John Doe"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Multiple Stores
|
|
203
|
+
|
|
204
|
+
You can create multiple independent stores using namespaces:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// Option 1: gstate with namespace
|
|
208
|
+
const userStore = gstate({ name: 'John' }, { namespace: 'users' })
|
|
209
|
+
const appStore = gstate({ theme: 'dark' }, { namespace: 'app' })
|
|
210
|
+
|
|
211
|
+
// In components - same key, different stores
|
|
212
|
+
const [name] = userStore('name') // 'John'
|
|
213
|
+
const [theme] = appStore('theme') // 'dark'
|
|
214
|
+
|
|
215
|
+
// Option 2: initState + useStore (global default store)
|
|
216
|
+
initState({ namespace: 'global' })
|
|
217
|
+
const [value, setValue] = useStore('key')
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Tip**: Keys are unique per-namespace, so you can use the same key name in different stores.
|
|
221
|
+
|
|
222
|
+
## 🚀 Advanced Superpowers
|
|
223
|
+
|
|
224
|
+
### 🔌 Official Plugin Ecosystem
|
|
225
|
+
|
|
226
|
+
Extend the core functionality dynamically with specialized modules.
|
|
227
|
+
|
|
228
|
+
1. **ImmerPlugin**: Adds `setWithProduce` for functional updates.
|
|
229
|
+
2. **UndoRedoPlugin**: Multi-level history management.
|
|
230
|
+
3. **PersistencePlugin**: Advanced storage with custom serialization.
|
|
231
|
+
4. **SyncPlugin**: Cross-tab state synchronization via BroadcastChannel.
|
|
232
|
+
5. **SchemaPlugin**: Runtime validation (perfect for Zod).
|
|
233
|
+
6. **DevToolsPlugin**: Redux DevTools integration.
|
|
234
|
+
7. **TTLPlugin**: Time-to-live management.
|
|
235
|
+
8. **AnalyticsPlugin**: Tracking bridge for metrics.
|
|
236
|
+
9. **SnapshotPlugin**: Manual state checkpointing.
|
|
237
|
+
10. **GuardPlugin**: Data transformation layer.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { createStore, PersistencePlugin, undoRedoPlugin } from 'argis'
|
|
241
|
+
|
|
242
|
+
const store = createStore()
|
|
243
|
+
store._addPlugin(PersistencePlugin({ storage: 'localStorage' }))
|
|
244
|
+
store._addPlugin(undoRedoPlugin({ limit: 50 }))
|
|
245
|
+
|
|
246
|
+
// Undo like a pro
|
|
247
|
+
store.undo()
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 🔬 Power Tools (Import from `rgs/advanced`)
|
|
251
|
+
|
|
252
|
+
Need the heavy artillery? We've got you covered.
|
|
253
|
+
|
|
254
|
+
- `createAsyncStore(fetcher)`: Atomic async state management.
|
|
255
|
+
- `StorageAdapters`: High-level interfaces for any storage engine.
|
|
256
|
+
- `Middleware / IPlugin`: Build your own extensions.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 📄 License
|
|
261
|
+
|
|
262
|
+
MIT © [Dario Passariello](https://github.com/dpassariello)
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
**Designed for those who build the future.**
|
|
267
|
+
Made with ❤️ and a lot of caffe' espresso!
|
package/dist/SECURITY.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createStore, StorageAdapters } from "./core/store";
|
|
2
|
+
import type { IStore, StoreConfig, PersistOptions, CustomStorage } from "./core/types";
|
|
3
|
+
import * as Security from "./core/security";
|
|
4
|
+
export declare const createStoreWithStorage: <S extends Record<string, unknown>>(storage: CustomStorage, config?: StoreConfig<S>) => IStore<S>;
|
|
5
|
+
export declare const createMemoryStore: <S extends Record<string, unknown>>(config?: StoreConfig<S>) => IStore<S>;
|
|
6
|
+
export declare const createSessionStore: <S extends Record<string, unknown>>(config?: StoreConfig<S>) => IStore<S> | null;
|
|
7
|
+
export { createStore, StorageAdapters, Security };
|
|
8
|
+
export type { IStore, StoreConfig, PersistOptions, CustomStorage };
|
|
9
|
+
export type { EncryptionKey, AuditEntry, Permission, AccessRule, ConsentRecord } from "./core/security";
|
package/dist/advanced.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as o,StorageAdapters as r}from"./core/store";import*as s from"./core/security";const S=(e,t)=>o({...t,storage:e}),i=e=>o({...e,storage:r.memory()}),c=e=>{const t=r.session();return t?o({...e,storage:t}):null};export{s as Security,r as StorageAdapters,i as createMemoryStore,c as createSessionStore,o as createStore,S as createStoreWithStorage};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createAsyncStore } from "./async";
|
|
2
|
+
export { StorageAdapters } from "./store";
|
|
3
|
+
export { syncPlugin as SyncPlugin } from "../plugins/official/sync.plugin";
|
|
4
|
+
export { analyticsPlugin as AnalyticsPlugin } from "../plugins/official/analytics.plugin";
|
|
5
|
+
export type { AsyncState, Middleware, IPlugin, PluginContext } from "./types";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IStore, AsyncState } from "../core/types";
|
|
2
|
+
export declare const createAsyncStore: <T>(resolver: () => Promise<T>, options?: {
|
|
3
|
+
key?: string;
|
|
4
|
+
persist?: boolean;
|
|
5
|
+
store?: IStore<Record<string, AsyncState<T>>>;
|
|
6
|
+
}) => IStore<Record<string, AsyncState<T>>> & {
|
|
7
|
+
execute: () => Promise<void>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IStore, StoreConfig, PersistOptions, StateUpdater } from "./types";
|
|
2
|
+
export declare const initState: <S extends Record<string, unknown>>(config?: StoreConfig<S>) => IStore<S>;
|
|
3
|
+
export declare const destroyState: () => void;
|
|
4
|
+
export declare const useIsStoreReady: (store?: IStore<Record<string, unknown>>) => boolean;
|
|
5
|
+
export declare const getStore: () => IStore<Record<string, unknown>> | null;
|
|
6
|
+
export declare const useStore: <T = unknown, S extends Record<string, unknown> = Record<string, unknown>>(key: string, store?: IStore<S>) => readonly [T | undefined, (val: T | StateUpdater<T>, options?: PersistOptions) => boolean];
|
|
7
|
+
export declare const useGState: <T = unknown, S extends Record<string, unknown> = Record<string, unknown>>(key: string, store?: IStore<S>) => readonly [T | undefined, (val: T | StateUpdater<T>, options?: PersistOptions) => boolean];
|
|
8
|
+
export declare const useSimpleState: <T = unknown, S extends Record<string, unknown> = Record<string, unknown>>(key: string, store?: IStore<S>) => readonly [T | undefined, (val: T | StateUpdater<T>, options?: PersistOptions) => boolean];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const isCryptoAvailable: boolean;
|
|
2
|
+
export interface EncryptionKey {
|
|
3
|
+
key: CryptoKey;
|
|
4
|
+
iv: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
export declare const generateEncryptionKey: () => Promise<EncryptionKey>;
|
|
7
|
+
export declare const exportKey: (encryptionKey: EncryptionKey) => Promise<{
|
|
8
|
+
key: string;
|
|
9
|
+
iv: string;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const importKey: (keyData: string, ivData: string) => Promise<EncryptionKey>;
|
|
12
|
+
export declare const encrypt: (data: unknown, encryptionKey: EncryptionKey) => Promise<string>;
|
|
13
|
+
export declare const decrypt: <T>(encryptedData: string, encryptionKey: EncryptionKey) => Promise<T>;
|
|
14
|
+
export interface AuditEntry {
|
|
15
|
+
timestamp: number;
|
|
16
|
+
action: 'set' | 'get' | 'delete' | 'hydrate';
|
|
17
|
+
key: string;
|
|
18
|
+
userId?: string;
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const setAuditLogger: (logger: (entry: AuditEntry) => void) => void;
|
|
23
|
+
export declare const isAuditActive: () => boolean;
|
|
24
|
+
export declare const logAudit: (entry: AuditEntry) => void;
|
|
25
|
+
export type Permission = 'read' | 'write' | 'delete' | 'admin';
|
|
26
|
+
export interface AccessRule {
|
|
27
|
+
pattern: string | ((key: string, userId?: string) => boolean);
|
|
28
|
+
permissions: Permission[];
|
|
29
|
+
}
|
|
30
|
+
export type AccessRulesMap = Map<string | ((key: string, userId?: string) => boolean), Permission[]>;
|
|
31
|
+
export declare const addAccessRule: (rules: AccessRulesMap, pattern: string | ((key: string, userId?: string) => boolean), perms: Permission[]) => void;
|
|
32
|
+
export declare const hasPermission: (rules: AccessRulesMap, key: string, action: Permission, _userId?: string) => boolean;
|
|
33
|
+
export declare const sanitizeValue: (value: unknown) => unknown;
|
|
34
|
+
export declare const validateKey: (key: string) => boolean;
|
|
35
|
+
export interface ConsentRecord {
|
|
36
|
+
id: string;
|
|
37
|
+
purpose: string;
|
|
38
|
+
granted: boolean;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
}
|
|
41
|
+
export type ConsentsMap = Map<string, ConsentRecord[]>;
|
|
42
|
+
export declare const recordConsent: (consents: ConsentsMap, userId: string, purpose: string, granted: boolean) => ConsentRecord;
|
|
43
|
+
export declare const hasConsent: (consents: ConsentsMap, userId: string, purpose: string) => boolean;
|
|
44
|
+
export declare const revokeConsent: (consents: ConsentsMap, userId: string, purpose: string) => ConsentRecord | null;
|
|
45
|
+
export declare const getConsents: (consents: ConsentsMap, userId: string) => ConsentRecord[];
|
|
46
|
+
export declare const exportUserData: (consents: ConsentsMap, userId: string) => {
|
|
47
|
+
userId: string;
|
|
48
|
+
exportedAt: number;
|
|
49
|
+
consents: ConsentRecord[];
|
|
50
|
+
};
|
|
51
|
+
export declare const deleteUserData: (consents: ConsentsMap, userId: string) => {
|
|
52
|
+
success: boolean;
|
|
53
|
+
deletedConsents: number;
|
|
54
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IStore, StoreConfig, CustomStorage } from './types';
|
|
2
|
+
export declare const StorageAdapters: {
|
|
3
|
+
local: () => CustomStorage | null;
|
|
4
|
+
session: () => CustomStorage | null;
|
|
5
|
+
memory: () => CustomStorage;
|
|
6
|
+
};
|
|
7
|
+
export declare const createStore: <S extends Record<string, unknown> = Record<string, unknown>>(config?: StoreConfig<S>) => IStore<S>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { EncryptionKey, AuditEntry, Permission, AccessRule } from './security';
|
|
2
|
+
export interface PersistOptions {
|
|
3
|
+
persist?: boolean;
|
|
4
|
+
secure?: 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(name: string, fn: (...args: unknown[]) => unknown): void;
|
|
59
|
+
_registerMethod(pluginName: string, methodName: string, fn: (...args: unknown[]) => unknown): void;
|
|
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
|
+
whenReady(): Promise<void>;
|
|
77
|
+
readonly plugins: GStatePlugins;
|
|
78
|
+
}
|
|
79
|
+
export interface GStatePlugins {
|
|
80
|
+
security: {
|
|
81
|
+
addAccessRule: (pattern: string | ((key: string, userId?: string) => boolean), permissions: Permission[]) => void;
|
|
82
|
+
recordConsent: (userId: string, purpose: string, granted: boolean) => import('./security').ConsentRecord;
|
|
83
|
+
hasConsent: (userId: string, purpose: string) => boolean;
|
|
84
|
+
getConsents: (userId: string) => import('./security').ConsentRecord[];
|
|
85
|
+
revokeConsent: (userId: string, purpose: string) => import('./security').ConsentRecord | null;
|
|
86
|
+
exportUserData: (userId: string) => {
|
|
87
|
+
userId: string;
|
|
88
|
+
exportedAt: number;
|
|
89
|
+
consents: import('./security').ConsentRecord[];
|
|
90
|
+
};
|
|
91
|
+
deleteUserData: (userId: string) => {
|
|
92
|
+
success: boolean;
|
|
93
|
+
deletedConsents: number;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
[key: string]: Record<string, (...args: any[]) => any>;
|
|
97
|
+
}
|
|
98
|
+
export interface StoreConfig<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
99
|
+
namespace?: string;
|
|
100
|
+
version?: number;
|
|
101
|
+
silent?: boolean;
|
|
102
|
+
debounceTime?: number;
|
|
103
|
+
storage?: CustomStorage | Storage;
|
|
104
|
+
migrate?: (oldState: Record<string, unknown>, oldVersion: number) => S;
|
|
105
|
+
onError?: (error: Error, context: {
|
|
106
|
+
operation: string;
|
|
107
|
+
key?: string;
|
|
108
|
+
}) => void;
|
|
109
|
+
maxObjectSize?: number;
|
|
110
|
+
maxTotalSize?: number;
|
|
111
|
+
encryptionKey?: EncryptionKey;
|
|
112
|
+
auditEnabled?: boolean;
|
|
113
|
+
userId?: string;
|
|
114
|
+
validateInput?: boolean;
|
|
115
|
+
accessRules?: Array<{
|
|
116
|
+
pattern: string | ((key: string, userId?: string) => boolean);
|
|
117
|
+
permissions: Permission[];
|
|
118
|
+
}>;
|
|
119
|
+
immer?: boolean;
|
|
120
|
+
}
|
|
121
|
+
export interface CustomStorage {
|
|
122
|
+
getItem(key: string): string | null;
|
|
123
|
+
setItem(key: string, value: string): void;
|
|
124
|
+
removeItem(key: string): void;
|
|
125
|
+
key(index: number): string | null;
|
|
126
|
+
length: number;
|
|
127
|
+
}
|
|
128
|
+
export interface AsyncState<T> {
|
|
129
|
+
data: T | null;
|
|
130
|
+
loading: boolean;
|
|
131
|
+
error: Error | null;
|
|
132
|
+
updatedAt: number | null;
|
|
133
|
+
}
|
|
134
|
+
export type { EncryptionKey, AuditEntry, Permission, AccessRule };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createStore as baseCreateStore } from "./core/store";
|
|
2
|
+
import { useStore as baseUseStore } from "./core/hooks";
|
|
3
|
+
import * as Security from "./core/security";
|
|
4
|
+
import type { IStore, StoreConfig } from "./core/types";
|
|
5
|
+
export declare const gstate: <S extends Record<string, unknown>>(initialState: S, configOrNamespace?: string | StoreConfig<S>) => IStore<S> & ((key: string) => unknown);
|
|
6
|
+
export { baseCreateStore as createStore };
|
|
7
|
+
export { useStore, useIsStoreReady, initState, destroyState, useStore as useGState, useStore as useSimpleState } from "./core/hooks";
|
|
8
|
+
export { createAsyncStore } from "./core/async";
|
|
9
|
+
export * from "./plugins/index";
|
|
10
|
+
export { generateEncryptionKey, exportKey, importKey, isCryptoAvailable, setAuditLogger, logAudit, validateKey, sanitizeValue } from "./core/security";
|
|
11
|
+
export declare const addAccessRule: (pattern: string | ((key: string, userId?: string) => boolean), perms: Security.Permission[]) => void | undefined;
|
|
12
|
+
export declare const hasPermission: (key: string, action: Security.Permission, uid?: string) => boolean;
|
|
13
|
+
export declare const recordConsent: (uid: string, p: string, g: boolean) => Security.ConsentRecord;
|
|
14
|
+
export declare const hasConsent: (uid: string, p: string) => boolean;
|
|
15
|
+
export declare const getConsents: (uid: string) => Security.ConsentRecord[];
|
|
16
|
+
export declare const revokeConsent: (uid: string, p: string) => Security.ConsentRecord | null | undefined;
|
|
17
|
+
export declare const exportUserData: (uid: string) => {
|
|
18
|
+
userId: string;
|
|
19
|
+
exportedAt: number;
|
|
20
|
+
consents: import("./core/security").ConsentRecord[];
|
|
21
|
+
};
|
|
22
|
+
export declare const deleteUserData: (uid: string) => {
|
|
23
|
+
success: boolean;
|
|
24
|
+
deletedConsents: number;
|
|
25
|
+
};
|
|
26
|
+
export declare const clearAccessRules: () => void;
|
|
27
|
+
export declare const clearAllConsents: () => void;
|
|
28
|
+
export type { EncryptionKey, AuditEntry, Permission, AccessRule, ConsentRecord } from "./core/security";
|
|
29
|
+
export type { IStore, StoreConfig, PersistOptions, StateUpdater, ComputedSelector, WatcherCallback } from "./core/types";
|
|
30
|
+
declare global {
|
|
31
|
+
var createStore: typeof baseCreateStore;
|
|
32
|
+
var gstate: <S extends Record<string, unknown>>(initialState: S, configOrNamespace?: string | StoreConfig<S>) => IStore<S> & ((key: string) => unknown);
|
|
33
|
+
var initState: typeof import("./core/hooks").initState;
|
|
34
|
+
var destroyState: typeof import("./core/hooks").destroyState;
|
|
35
|
+
var gState: IStore<Record<string, unknown>>;
|
|
36
|
+
var useStore: typeof baseUseStore;
|
|
37
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as i}from"./core/store";import{useStore as c,getStore as r}from"./core/hooks";import"./core/security";import{useStore as R,useIsStoreReady as U,initState as E,destroyState as I,useStore as D,useStore as P}from"./core/hooks";import{createAsyncStore as j}from"./core/async";export*from"./plugins/index";import{generateEncryptionKey as z,exportKey as G,importKey as L,isCryptoAvailable as V,setAuditLogger as W,logAudit as _,validateKey as q,sanitizeValue as B}from"./core/security";const d=(t,e)=>{const o=i(typeof e=="string"?{namespace:e}:e);return t&&Object.entries(t).forEach(([n,a])=>{o._setSilently(n,a)}),Object.assign(n=>c(n,o),o)};const f=(t,e)=>r()?.addAccessRule(t,e),l=(t,e,s)=>r()?.hasPermission(t,e,s)??!0,y=(t,e,s)=>{const o=r();if(!o)throw new Error("[gState] recordConsent failed: No store found. call initState() first.");return o.recordConsent(t,e,s)},m=(t,e)=>r()?.hasConsent(t,e)??!1,x=t=>r()?.getConsents(t)??[],C=(t,e)=>r()?.revokeConsent(t,e),k=t=>{const e=r();if(!e)throw new Error("[gState] exportUserData failed: No store found.");return e.exportUserData(t)},b=t=>{const e=r();if(!e)throw new Error("[gState] deleteUserData failed: No store found.");return e.deleteUserData(t)},h=()=>{},w=()=>{};export{f as addAccessRule,h as clearAccessRules,w as clearAllConsents,j as createAsyncStore,i as createStore,b as deleteUserData,I as destroyState,G as exportKey,k as exportUserData,z as generateEncryptionKey,x as getConsents,d as gstate,m as hasConsent,l as hasPermission,L as importKey,E as initState,V as isCryptoAvailable,_ as logAudit,y as recordConsent,C as revokeConsent,B as sanitizeValue,W as setAuditLogger,D as useGState,U as useIsStoreReady,P as useSimpleState,R as useStore,q as validateKey};
|