@biglogic/rgs 3.5.1 → 3.5.3
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/FUNDING.yml +12 -0
- package/README.md +68 -12
- package/core/hooks.d.ts +10 -0
- package/core/sync.d.ts +75 -0
- package/core/types.d.ts +7 -0
- package/index.d.ts +3 -0
- package/index.js +2 -1
- package/index.js.map +7 -0
- package/package.json +11 -7
- package/rgs-extension.vsix +0 -0
- package/advanced.js +0 -1
- /package/{LICENSE → LICENSE.md} +0 -0
package/FUNDING.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: passariello
|
|
4
|
+
patreon: passariello
|
|
5
|
+
ko_fi: passariello
|
|
6
|
+
liberapay: passariello
|
|
7
|
+
issuehunt: passariello
|
|
8
|
+
custom:
|
|
9
|
+
[
|
|
10
|
+
"https://dario.passariello.ca",
|
|
11
|
+
"https://www.indiegogo.com/individuals/28513718",
|
|
12
|
+
]
|
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|

|
|
13
13
|

|
|
14
14
|

|
|
15
|
+

|
|
15
16
|

|
|
16
17
|

|
|
17
18
|
|
|
@@ -36,18 +37,18 @@ We took the simplicity of **Reactive Global State (RGS)** and fused it with the
|
|
|
36
37
|
|
|
37
38
|
## gState vs useState
|
|
38
39
|
|
|
39
|
-
| Feature |
|
|
40
|
-
|
|
41
|
-
| **Global state across components** | ❌ Need Context/props |
|
|
42
|
-
| **Provider wrapper** |
|
|
43
|
-
| **Persistence (localStorage)** |
|
|
44
|
-
| **Data encryption** |
|
|
45
|
-
| **Multiple namespaces/stores** |
|
|
46
|
-
| **Plugins (Immer, Undo/Redo)** |
|
|
47
|
-
| **Audit logging** |
|
|
48
|
-
| **RBAC/GDPR consent** |
|
|
49
|
-
| **SSR/Hydration** |
|
|
50
|
-
| **Computed values** |
|
|
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** | ✅ | ❌ |
|
|
51
52
|
|
|
52
53
|
### When to use what?
|
|
53
54
|
|
|
@@ -72,6 +73,7 @@ We took the simplicity of **Reactive Global State (RGS)** and fused it with the
|
|
|
72
73
|
| **Security** | 🛡️ **AES-256 + RBAC** | ❌ None | ❌ Ecosystem | ❌ None |
|
|
73
74
|
| **Persistence** | 💾 **First-class** | 🔌 Middleware | 🔌 Middleware | 🔌 Effects |
|
|
74
75
|
| **Async** | ✅ **Atomic** | ✅ Async/Await | ✅ Thunks | ✅ Suspense |
|
|
76
|
+
| **Local-First Sync** | ✅ **Built-in** | ❌ None | ❌ None | ❌ None |
|
|
75
77
|
| **Bundle Size** | **~2kB** | ~1kB | >10kB | >20kB |
|
|
76
78
|
|
|
77
79
|
> **RGS** is the only library on the market that treats **Security** and **Persistence** as first-class citizens.
|
|
@@ -234,6 +236,41 @@ const store = gstate({ data: {} }, {
|
|
|
234
236
|
})
|
|
235
237
|
```
|
|
236
238
|
|
|
239
|
+
### Local-First Sync (Offline-by-Default)
|
|
240
|
+
|
|
241
|
+
RGS now includes a powerful Local-First Sync Engine that makes your app work offline by default:
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { gstate, useSyncedState } from '@biglogic/rgs'
|
|
245
|
+
|
|
246
|
+
// Create store with built-in sync
|
|
247
|
+
const store = gstate({
|
|
248
|
+
todos: [],
|
|
249
|
+
user: null
|
|
250
|
+
}, {
|
|
251
|
+
namespace: 'myapp',
|
|
252
|
+
sync: {
|
|
253
|
+
endpoint: 'https://api.example.com/sync',
|
|
254
|
+
authToken: 'your-token',
|
|
255
|
+
autoSyncInterval: 30000, // Sync every 30s
|
|
256
|
+
syncOnReconnect: true, // Auto-sync when back online
|
|
257
|
+
strategy: 'last-write-wins' // Conflict resolution
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
// Use in React - automatically synced!
|
|
262
|
+
function TodoList() {
|
|
263
|
+
const [todos, setTodos] = useSyncedState('todos')
|
|
264
|
+
|
|
265
|
+
// Works offline automatically
|
|
266
|
+
const addTodo = (text) => {
|
|
267
|
+
setTodos([...todos, { id: Date.now(), text }])
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return <div>{/* ... */}</div>
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
237
274
|
---
|
|
238
275
|
|
|
239
276
|
## Multiple Stores
|
|
@@ -272,6 +309,7 @@ Extend the core functionality dynamically with specialized modules.
|
|
|
272
309
|
8. **AnalyticsPlugin**: Tracking bridge for metrics.
|
|
273
310
|
9. **SnapshotPlugin**: Manual state checkpointing.
|
|
274
311
|
10. **GuardPlugin**: Data transformation layer.
|
|
312
|
+
11. **Local-First Sync**: Built-in offline-first with auto-sync (NEW!)
|
|
275
313
|
|
|
276
314
|
```typescript
|
|
277
315
|
import { createStore, PersistencePlugin, undoRedoPlugin } from '@biglogic/rgs'
|
|
@@ -294,6 +332,24 @@ Need the heavy artillery? We've got you covered.
|
|
|
294
332
|
|
|
295
333
|
---
|
|
296
334
|
|
|
335
|
+
## 🛡️ Quality & Testing
|
|
336
|
+
|
|
337
|
+
RGS is built with an obsession for reliability. Our test suite covers multiple layers to ensure zero-regressions:
|
|
338
|
+
|
|
339
|
+
- **Unit Tests (Jest)**: 100+ tests covering core logic, stores, and hooks.
|
|
340
|
+
- **E2E Tests (Playwright)**: Real-world browser testing for cross-tab synchronization and Web Crypto API.
|
|
341
|
+
- **Concurrency Testing**: Verification of race conditions in multi-tab environments.
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Run unit tests
|
|
345
|
+
npm run test
|
|
346
|
+
|
|
347
|
+
# Run E2E tests
|
|
348
|
+
npm run test:e2e
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
297
353
|
## 📄 License
|
|
298
354
|
|
|
299
355
|
MIT © [Dario Passariello](https://github.com/dpassariello)
|
package/core/hooks.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import type { IStore, StoreConfig, PersistOptions, StateUpdater } from "./types";
|
|
2
|
+
import { SyncEngine, SyncConfig, SyncState } from "./sync";
|
|
2
3
|
export declare const initState: <S extends Record<string, unknown>>(config?: StoreConfig<S>) => IStore<S>;
|
|
3
4
|
export declare const destroyState: () => void;
|
|
4
5
|
export declare const useIsStoreReady: (store?: IStore<Record<string, unknown>>) => boolean;
|
|
5
6
|
export declare const getStore: () => IStore<Record<string, unknown>> | null;
|
|
6
7
|
export declare function useStore<T, S extends Record<string, unknown> = Record<string, unknown>>(selector: (state: S) => T, store?: IStore<S>): T;
|
|
7
8
|
export declare function 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];
|
|
9
|
+
export declare const initSync: (store: IStore<Record<string, unknown>>, config: SyncConfig) => SyncEngine<Record<string, unknown>>;
|
|
10
|
+
export declare const destroySync: (namespace: string) => void;
|
|
11
|
+
export declare function useSyncedState<T = unknown>(key: string, store?: IStore<Record<string, unknown>>): readonly [
|
|
12
|
+
T | undefined,
|
|
13
|
+
(val: T | StateUpdater<T>, options?: PersistOptions) => boolean,
|
|
14
|
+
SyncState
|
|
15
|
+
];
|
|
16
|
+
export declare const useSyncStatus: () => SyncState;
|
|
17
|
+
export declare const triggerSync: (namespace?: string) => Promise<void>;
|
package/core/sync.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { IStore } from "./types";
|
|
2
|
+
export type SyncStrategy = 'last-write-wins' | 'merge' | 'crdt' | 'server-wins' | 'client-wins';
|
|
3
|
+
export interface SyncConfig {
|
|
4
|
+
endpoint: string;
|
|
5
|
+
authToken?: string;
|
|
6
|
+
strategy?: SyncStrategy;
|
|
7
|
+
autoSyncInterval?: number;
|
|
8
|
+
syncOnReconnect?: boolean;
|
|
9
|
+
debounceTime?: number;
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
onSync?: (result: SyncResult) => void;
|
|
12
|
+
onConflict?: (conflict: ConflictInfo) => ConflictResolution;
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface SyncResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
syncedKeys: string[];
|
|
18
|
+
conflicts: ConflictInfo[];
|
|
19
|
+
errors: string[];
|
|
20
|
+
timestamp: number;
|
|
21
|
+
duration: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ConflictInfo {
|
|
24
|
+
key: string;
|
|
25
|
+
localValue: unknown;
|
|
26
|
+
remoteValue: unknown;
|
|
27
|
+
localVersion: number;
|
|
28
|
+
remoteVersion: number;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
}
|
|
31
|
+
export type ConflictResolution = {
|
|
32
|
+
action: 'accept-local';
|
|
33
|
+
} | {
|
|
34
|
+
action: 'accept-remote';
|
|
35
|
+
} | {
|
|
36
|
+
action: 'merge';
|
|
37
|
+
value: unknown;
|
|
38
|
+
} | {
|
|
39
|
+
action: 'discard';
|
|
40
|
+
};
|
|
41
|
+
export interface SyncState {
|
|
42
|
+
isOnline: boolean;
|
|
43
|
+
isSyncing: boolean;
|
|
44
|
+
lastSyncTimestamp: number | null;
|
|
45
|
+
pendingChanges: number;
|
|
46
|
+
conflicts: number;
|
|
47
|
+
}
|
|
48
|
+
export declare class SyncEngine<S extends Record<string, unknown> = Record<string, unknown>> {
|
|
49
|
+
private store;
|
|
50
|
+
private config;
|
|
51
|
+
private pendingQueue;
|
|
52
|
+
private remoteVersions;
|
|
53
|
+
private syncTimer;
|
|
54
|
+
private onlineStatusListeners;
|
|
55
|
+
private syncStateListeners;
|
|
56
|
+
private _isOnline;
|
|
57
|
+
private _isSyncing;
|
|
58
|
+
constructor(store: IStore<S>, config: SyncConfig);
|
|
59
|
+
private _setupOnlineListener;
|
|
60
|
+
private _setupStoreListener;
|
|
61
|
+
private _startAutoSync;
|
|
62
|
+
private _notifyOnlineChange;
|
|
63
|
+
private _notifyStateChange;
|
|
64
|
+
queueChange(key: string, value: unknown): void;
|
|
65
|
+
sync(): Promise<SyncResult>;
|
|
66
|
+
private _fetchRemoteVersions;
|
|
67
|
+
private _pushChange;
|
|
68
|
+
private _resolveConflict;
|
|
69
|
+
getState(): SyncState;
|
|
70
|
+
onOnlineChange(callback: (online: boolean) => void): () => void;
|
|
71
|
+
onStateChange(callback: (state: SyncState) => void): () => void;
|
|
72
|
+
flush(): Promise<SyncResult>;
|
|
73
|
+
destroy(): void;
|
|
74
|
+
}
|
|
75
|
+
export declare const createSyncEngine: <S extends Record<string, unknown>>(store: IStore<S>, config: SyncConfig) => SyncEngine<S>;
|
package/core/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EncryptionKey, AuditEntry, Permission, AccessRule } from './security';
|
|
2
|
+
import type { SyncConfig } from './sync';
|
|
2
3
|
export interface PersistOptions {
|
|
3
4
|
persist?: boolean;
|
|
4
5
|
secure?: boolean;
|
|
@@ -111,6 +112,11 @@ export interface GStatePlugins {
|
|
|
111
112
|
}>;
|
|
112
113
|
getStats: () => import('../plugins/official/cloud-sync.plugin').SyncStats;
|
|
113
114
|
};
|
|
115
|
+
sync: {
|
|
116
|
+
flush: () => Promise<import('../core/sync').SyncResult>;
|
|
117
|
+
getState: () => import('../core/sync').SyncState;
|
|
118
|
+
onStateChange: (callback: (state: import('../core/sync').SyncState) => void) => () => void;
|
|
119
|
+
};
|
|
114
120
|
logger: Record<string, never>;
|
|
115
121
|
[key: string]: unknown;
|
|
116
122
|
}
|
|
@@ -140,6 +146,7 @@ export interface StoreConfig<S extends Record<string, unknown> = Record<string,
|
|
|
140
146
|
permissions: Permission[];
|
|
141
147
|
}>;
|
|
142
148
|
immer?: boolean;
|
|
149
|
+
sync?: SyncConfig;
|
|
143
150
|
}
|
|
144
151
|
export interface CustomStorage {
|
|
145
152
|
getItem(key: string): string | null;
|
package/index.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export declare const gstate: <S extends Record<string, unknown>>(initialState: S
|
|
|
6
6
|
export { baseCreateStore as createStore };
|
|
7
7
|
export { useStore, useIsStoreReady, initState, getStore, destroyState, useStore as useGState, useStore as useSimpleState } from "./core/hooks";
|
|
8
8
|
export { createAsyncStore } from "./core/async";
|
|
9
|
+
export { SyncEngine, createSyncEngine } from "./core/sync";
|
|
10
|
+
export type { SyncConfig, SyncState, SyncResult, SyncStrategy, ConflictInfo, ConflictResolution } from "./core/sync";
|
|
11
|
+
export { initSync, destroySync, useSyncedState, useSyncStatus, triggerSync } from "./core/hooks";
|
|
9
12
|
export * from "./plugins/index";
|
|
10
13
|
export { generateEncryptionKey, exportKey, importKey, isCryptoAvailable, setAuditLogger, logAudit, validateKey, sanitizeValue } from "./core/security";
|
|
11
14
|
export declare const addAccessRule: (pattern: string | ((key: string, userId?: string) => boolean), perms: Security.Permission[]) => void | undefined;
|
package/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
var yt=Symbol.for("immer-nothing"),it=Symbol.for("immer-draftable"),R=Symbol.for("immer-state");function T(e,...t){throw new Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var M=Object,q=M.getPrototypeOf,Se="constructor",Pe="prototype",$e="configurable",he="enumerable",ge="writable",ne="value",j=e=>!!e&&!!e[R];function U(e){return e?St(e)||ke(e)||!!e[it]||!!e[Se]?.[it]||ve(e)||xe(e):!1}var Wt=M[Pe][Se].toString(),at=new WeakMap;function St(e){if(!e||!Je(e))return!1;let t=q(e);if(t===null||t===M[Pe])return!0;let n=M.hasOwnProperty.call(t,Se)&&t[Se];if(n===Object)return!0;if(!G(n))return!1;let r=at.get(n);return r===void 0&&(r=Function.toString.call(n),at.set(n,r)),r===Wt}function Ee(e,t,n=!0){se(e)===0?(n?Reflect.ownKeys(e):M.keys(e)).forEach(o=>{t(o,e[o],e)}):e.forEach((r,o)=>t(o,r,e))}function se(e){let t=e[R];return t?t.type_:ke(e)?1:ve(e)?2:xe(e)?3:0}var ct=(e,t,n=se(e))=>n===2?e.has(t):M[Pe].hasOwnProperty.call(e,t),Fe=(e,t,n=se(e))=>n===2?e.get(t):e[t],me=(e,t,n,r=se(e))=>{r===2?e.set(t,n):r===3?e.add(n):e[t]=n};function Ht(e,t){return e===t?e!==0||1/e===1/t:e!==e&&t!==t}var ke=Array.isArray,ve=e=>e instanceof Map,xe=e=>e instanceof Set,Je=e=>typeof e=="object",G=e=>typeof e=="function",Ne=e=>typeof e=="boolean";function Jt(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var N=e=>e.copy_||e.base_;var Ge=e=>e.modified_?e.copy_:e.base_;function je(e,t){if(ve(e))return new Map(e);if(xe(e))return new Set(e);if(ke(e))return Array[Pe].slice.call(e);let n=St(e);if(t===!0||t==="class_only"&&!n){let r=M.getOwnPropertyDescriptors(e);delete r[R];let o=Reflect.ownKeys(r);for(let s=0;s<o.length;s++){let a=o[s],u=r[a];u[ge]===!1&&(u[ge]=!0,u[$e]=!0),(u.get||u.set)&&(r[a]={[$e]:!0,[ge]:!0,[he]:u[he],[ne]:e[a]})}return M.create(q(e),r)}else{let r=q(e);if(r!==null&&n)return{...e};let o=M.create(r);return M.assign(o,e)}}function $(e,t=!1){return Ce(e)||j(e)||!U(e)||(se(e)>1&&M.defineProperties(e,{set:pe,add:pe,clear:pe,delete:pe}),M.freeze(e),t&&Ee(e,(n,r)=>{$(r,!0)},!1)),e}function Gt(){T(2)}var pe={[ne]:Gt};function Ce(e){return e===null||!Je(e)?!0:M.isFrozen(e)}var _e="MapSet",Le="Patches",ut="ArrayMethods",ht={};function H(e){let t=ht[e];return t||T(0,e),t}var lt=e=>!!ht[e];var re,mt=()=>re,qt=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:lt(_e)?H(_e):void 0,arrayMethodsPlugin_:lt(ut)?H(ut):void 0});function ft(e,t){t&&(e.patchPlugin_=H(Le),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Be(e){Ke(e),e.drafts_.forEach(Qt),e.drafts_=null}function Ke(e){e===re&&(re=e.parent_)}var dt=e=>re=qt(re,e);function Qt(e){let t=e[R];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function pt(e,t){t.unfinalizedDrafts_=t.drafts_.length;let n=t.drafts_[0];if(e!==void 0&&e!==n){n[R].modified_&&(Be(t),T(4)),U(e)&&(e=gt(t,e));let{patchPlugin_:o}=t;o&&o.generateReplacementPatches_(n[R].base_,e,t)}else e=gt(t,n);return Xt(t,e,!0),Be(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e!==yt?e:void 0}function gt(e,t){if(Ce(t))return t;let n=t[R];if(!n)return we(t,e.handledSet_,e);if(!Re(n,e))return t;if(!n.modified_)return n.base_;if(!n.finalized_){let{callbacks_:r}=n;if(r)for(;r.length>0;)r.pop()(e);bt(n,e)}return n.copy_}function Xt(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&$(t,n)}function _t(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var Re=(e,t)=>e.scope_===t,Yt=[];function wt(e,t,n,r){let o=N(e),s=e.type_;if(r!==void 0&&Fe(o,r,s)===t){me(o,r,n,s);return}if(!e.draftLocations_){let u=e.draftLocations_=new Map;Ee(o,(p,d)=>{if(j(d)){let h=u.get(d)||[];h.push(p),u.set(d,h)}})}let a=e.draftLocations_.get(t)??Yt;for(let u of a)me(o,u,n,s)}function Zt(e,t,n){e.callbacks_.push(function(o){let s=t;if(!s||!Re(s,o))return;o.mapSetPlugin_?.fixSetContents(s);let a=Ge(s);wt(e,s.draft_??s,a,n),bt(s,o)})}function bt(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||e.type_===1&&e.allIndicesReassigned_||(e.assigned_?.size??0)>0)){let{patchPlugin_:r}=t;if(r){let o=r.getPath(e);o&&r.generatePatches_(e,o,t)}_t(e)}}function en(e,t,n){let{scope_:r}=e;if(j(n)){let o=n[R];Re(o,r)&&o.callbacks_.push(function(){ye(e);let a=Ge(o);wt(e,n,a,t)})}else U(n)&&e.callbacks_.push(function(){let s=N(e);e.type_===3?s.has(n)&&we(n,r.handledSet_,r):Fe(s,t,e.type_)===n&&r.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&we(Fe(e.copy_,t,e.type_),r.handledSet_,r)})}function we(e,t,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||j(e)||t.has(e)||!U(e)||Ce(e)||(t.add(e),Ee(e,(r,o)=>{if(j(o)){let s=o[R];if(Re(s,n)){let a=Ge(s);me(e,r,a,e.type_),_t(s)}}else U(o)&&we(o,t,n)})),e}function tn(e,t){let n=ke(e),r={type_:n?1:0,scope_:t?t.scope_:mt(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0},o=r,s=be;n&&(o=[r],s=oe);let{revoke:a,proxy:u}=Proxy.revocable(o,s);return r.draft_=u,r.revoke_=a,[u,r]}var be={get(e,t){if(t===R)return e;let n=e.scope_.arrayMethodsPlugin_,r=e.type_===1&&typeof t=="string";if(r&&n?.isArrayOperationMethod(t))return n.createMethodInterceptor(e,t);let o=N(e);if(!ct(o,t,e.type_))return nn(e,o,t);let s=o[t];if(e.finalized_||!U(s)||r&&e.operationMethod&&n?.isMutatingArrayMethod(e.operationMethod)&&Jt(t))return s;if(s===Ue(e.base_,t)){ye(e);let a=e.type_===1?+t:t,u=He(e.scope_,s,e,a);return e.copy_[a]=u}return s},has(e,t){return t in N(e)},ownKeys(e){return Reflect.ownKeys(N(e))},set(e,t,n){let r=Pt(N(e),t);if(r?.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){let o=Ue(N(e),t),s=o?.[R];if(s&&s.base_===n)return e.copy_[t]=n,e.assigned_.set(t,!1),!0;if(Ht(n,o)&&(n!==void 0||ct(e.base_,t,e.type_)))return!0;ye(e),We(e)}return e.copy_[t]===n&&(n!==void 0||t in e.copy_)||Number.isNaN(n)&&Number.isNaN(e.copy_[t])||(e.copy_[t]=n,e.assigned_.set(t,!0),en(e,t,n)),!0},deleteProperty(e,t){return ye(e),Ue(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),We(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let n=N(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{[ge]:!0,[$e]:e.type_!==1||t!=="length",[he]:r[he],[ne]:n[t]}},defineProperty(){T(11)},getPrototypeOf(e){return q(e.base_)},setPrototypeOf(){T(12)}},oe={};for(let e in be){let t=be[e];oe[e]=function(){let n=arguments;return n[0]=n[0][0],t.apply(this,n)}}oe.deleteProperty=function(e,t){return oe.set.call(this,e,t,void 0)};oe.set=function(e,t,n){return be.set.call(this,e[0],t,n,e[0])};function Ue(e,t){let n=e[R];return(n?N(n):e)[t]}function nn(e,t,n){let r=Pt(t,n);return r?ne in r?r[ne]:r.get?.call(e.draft_):void 0}function Pt(e,t){if(!(t in e))return;let n=q(e);for(;n;){let r=Object.getOwnPropertyDescriptor(n,t);if(r)return r;n=q(n)}}function We(e){e.modified_||(e.modified_=!0,e.parent_&&We(e.parent_))}function ye(e){e.copy_||(e.assigned_=new Map,e.copy_=je(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var rn=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(t,n,r)=>{if(G(t)&&!G(n)){let s=n;n=t;let a=this;return function(p=s,...d){return a.produce(p,h=>n.call(this,h,...d))}}G(n)||T(6),r!==void 0&&!G(r)&&T(7);let o;if(U(t)){let s=dt(this),a=He(s,t,void 0),u=!0;try{o=n(a),u=!1}finally{u?Be(s):Ke(s)}return ft(s,r),pt(o,s)}else if(!t||!Je(t)){if(o=n(t),o===void 0&&(o=t),o===yt&&(o=void 0),this.autoFreeze_&&$(o,!0),r){let s=[],a=[];H(Le).generateReplacementPatches_(t,o,{patches_:s,inversePatches_:a}),r(s,a)}return o}else T(1,t)},this.produceWithPatches=(t,n)=>{if(G(t))return(a,...u)=>this.produceWithPatches(a,p=>t(p,...u));let r,o;return[this.produce(t,n,(a,u)=>{r=a,o=u}),r,o]},Ne(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),Ne(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),Ne(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){U(e)||T(8),j(e)&&(e=on(e));let t=dt(this),n=He(t,e,void 0);return n[R].isManual_=!0,Ke(t),n}finishDraft(e,t){let n=e&&e[R];(!n||!n.isManual_)&&T(9);let{scope_:r}=n;return ft(r,t),pt(void 0,r)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let n;for(n=t.length-1;n>=0;n--){let o=t[n];if(o.path.length===0&&o.op==="replace"){e=o.value;break}}n>-1&&(t=t.slice(n+1));let r=H(Le).applyPatches_;return j(e)?r(e,t):this.produce(e,o=>r(o,t))}};function He(e,t,n,r){let[o,s]=ve(t)?H(_e).proxyMap_(t,n):xe(t)?H(_e).proxySet_(t,n):tn(t,n);return(n?.scope_??mt()).drafts_.push(o),s.callbacks_=n?.callbacks_??[],s.key_=r,n&&r!==void 0?Zt(n,s,r):s.callbacks_.push(function(p){p.mapSetPlugin_?.fixSetContents(s);let{patchPlugin_:d}=p;s.modified_&&d&&d.generatePatches_(s,[],p)}),o}function on(e){return j(e)||T(10,e),Et(e)}function Et(e){if(!U(e)||Ce(e))return e;let t=e[R],n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=je(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=je(e,!0);return Ee(n,(o,s)=>{me(n,o,Et(s))},r),t&&(t.finalized_=!1),n}var sn=new rn,kt=sn.produce;var vt=typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof crypto.subtle.generateKey=="function",an=async()=>{if(!vt)throw new Error("Web Crypto API not available");let e=await crypto.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),t=crypto.getRandomValues(new Uint8Array(12));return{key:e,iv:t}},cn=async e=>{let t=await crypto.subtle.exportKey("raw",e.key);return{key:btoa(String.fromCharCode(...new Uint8Array(t))),iv:btoa(String.fromCharCode(...e.iv))}},un=async(e,t)=>{let n=Uint8Array.from(atob(e),s=>s.charCodeAt(0)),r=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return{key:await crypto.subtle.importKey("raw",n,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),iv:r}},xt=async(e,t)=>{let n=new TextEncoder,r=n.encode(JSON.stringify(e)),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:t.iv},t.key,r),s=new Uint8Array(t.iv.length+o.byteLength);return s.set(t.iv),s.set(new Uint8Array(o),t.iv.length),btoa(String.fromCharCode(...s))},Ct=async(e,t)=>{let n=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),r=n.slice(0,12),o=n.slice(12),s=await crypto.subtle.decrypt({name:"AES-GCM",iv:r},t.key,o);return JSON.parse(new TextDecoder().decode(s))},Ie=null,ln=e=>{Ie=e},Rt=()=>Ie!==null,ae=e=>{Ie&&Ie(e)},qe=(e,t,n)=>{e.set(t instanceof RegExp?t.source:t,n)},Ae=(e,t,n,r)=>{if(e.size===0)return!0;for(let[o,s]of e){let a;if(typeof o=="function")a=o(t,r);else try{a=new RegExp(o).test(t)}catch{continue}if(a)return s.includes(n)||s.includes("admin")}return!1},ie=e=>{if(typeof e=="string"){let t=e.replace(/&#[xX]?[0-9a-fA-F]+;?/g,r=>{let o=r.match(/&#x([0-9a-fA-F]+);?/i);if(o&&o[1])return String.fromCharCode(parseInt(o[1],16));let s=r.match(/&#([0-9]+);?/);return s&&s[1]?String.fromCharCode(parseInt(s[1],10)):""});try{t=decodeURIComponent(t)}catch{}return t.replace(/\b(javascript|vbscript|data:text\/html|about:blank|chrome:)/gi,"[SEC-REMOVED]").replace(/<script\b[^>]*>[\s\S]*?<\s*\/\s*script\b[^>]*>/gi,"[SEC-REMOVED]").replace(/on\w+\s*=/gi,"[SEC-REMOVED]=").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,"[SEC-REMOVED]").replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi,"[SEC-REMOVED]").replace(/<embed\b[^<]*(?:(?!<\/embed>)<[^<]*)*<\/embed>/gi,"[SEC-REMOVED]").replace(/<svg\b[^<]*(?:(?!<\/svg>)<[^<]*)*<\/svg>/gi,"[SEC-REMOVED]").replace(/<form\b[^<]*(?:(?!<\/form>)<[^<]*)*<\/form>/gi,"[SEC-REMOVED]").replace(/<base\b[^<]*(?:(?!<\/base>)<[^<]*)*<\/base>/gi,"[SEC-REMOVED]").replace(/<link\b[^<]*(?:(?!<\/link>)<[^<]*)*<\/link>/gi,"[SEC-REMOVED]").replace(/<meta\b[^<]*(?:(?!<\/meta>)<[^<]*)*<\/meta>/gi,"[SEC-REMOVED]").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,"[SEC-REMOVED]")}if(e&&typeof e=="object"&&!Array.isArray(e)){if(Object.getPrototypeOf(e)===Object.prototype){let t={};for(let[n,r]of Object.entries(e))t[n]=ie(r);return t}return e}return Array.isArray(e)?e.map(t=>ie(t)):e},Qe=e=>/^[a-zA-Z0-9_.-]+$/.test(e)&&e.length<=256,Xe=(e,t,n,r)=>{let o={id:crypto.randomUUID(),purpose:n,granted:r,timestamp:Date.now()},s=e.get(t)||[];return s.push(o),e.set(t,s),ae({timestamp:Date.now(),action:"set",key:`consent:${n}`,userId:t,success:!0}),o},It=(e,t,n)=>{let r=e.get(t);if(!r)return!1;for(let o=r.length-1;o>=0;o--){let s=r[o];if(s&&s.purpose===n)return s.granted}return!1},At=(e,t,n)=>Xe(e,t,n,!1),Mt=(e,t)=>e.get(t)||[],Dt=(e,t)=>({userId:t,exportedAt:Date.now(),consents:e.get(t)||[]}),Ot=(e,t)=>{let n=e.get(t)?.length||0;return e.delete(t),{success:!0,deletedConsents:n}};var Q=e=>{if(e===null||typeof e!="object")return e;if(typeof structuredClone=="function")try{return structuredClone(e)}catch{}let t=new WeakMap,n=r=>{if(r===null||typeof r!="object"||typeof r=="function")return r;if(t.has(r))return t.get(r);if(r instanceof Date)return new Date(r.getTime());if(r instanceof RegExp)return new RegExp(r.source,r.flags);if(r instanceof Map){let a=new Map;return t.set(r,a),r.forEach((u,p)=>a.set(n(p),n(u))),a}if(r instanceof Set){let a=new Set;return t.set(r,a),r.forEach(u=>a.add(n(u))),a}let o=Array.isArray(r)?[]:Object.create(Object.getPrototypeOf(r));t.set(r,o);let s=[...Object.keys(r),...Object.getOwnPropertySymbols(r)];for(let a of s)o[a]=n(r[a]);return o};return n(e)},ce=(e,t)=>{if(e===t)return!0;if(e===null||t===null||typeof e!="object"||typeof t!="object")return e===t;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let o=0;o<e.length;o++)if(!ce(e[o],t[o]))return!1;return!0}let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let o=0;o<n.length;o++){let s=n[o];if(!(s in t)||!ce(e[s],t[s]))return!1}return!0};var zt=e=>`${e}_`,Vt=async e=>{if(!e.storage)return;let{store:t,config:n,diskQueue:r,storage:o,encryptionKey:s,audit:a,onError:u,silent:p,currentVersion:d}=e,h=zt(n.namespace||"gstate");try{let _={};t.forEach((y,b)=>{_[b]=y});let l,S=n?.encoded;S?l=btoa(JSON.stringify(_)):l=JSON.stringify(_),o.setItem(h.replace("_",""),JSON.stringify({v:1,t:Date.now(),e:null,d:l,_sys_v:d,_b64:S?!0:void 0})),a("set","FULL_STATE",!0)}catch(_){let l=_ instanceof Error?_:new Error(String(_));u?u(l,{operation:"persist",key:"FULL_STATE"}):p||console.error("[gState] Persist failed: ",l)}let m=Array.from(r.entries());r.clear();for(let[_,l]of m)try{let S=l.value,y=l.options.encoded||l.options.secure;if(l.options.encrypted){if(!s)throw new Error(`Encryption key missing for "${_}"`);S=await xt(l.value,s)}else y?S=btoa(JSON.stringify(l.value)):typeof l.value=="object"&&l.value!==null&&(S=JSON.stringify(l.value));o.setItem(`${h}${_}`,JSON.stringify({v:e.versions.get(_)||1,t:Date.now(),e:l.options.ttl?Date.now()+l.options.ttl:null,d:S,_sys_v:d,_enc:l.options.encrypted?!0:void 0,_b64:y?!0:void 0})),a("set",_,!0)}catch(S){let y=S instanceof Error?S:new Error(String(S));u?u(y,{operation:"persist",key:_}):p||console.error("[gState] Persist failed: ",y)}},Nt=async(e,t,n)=>{let{storage:r,config:o,encryptionKey:s,audit:a,onError:u,silent:p,currentVersion:d,store:h,sizes:m,versions:_}=e,l=zt(o.namespace||"gstate"),S=o.immer??!0;if(r)try{let y={},b=0;for(let I=0;I<(r.length||0);I++){let k=r.key(I);if(!k||!k.startsWith(l))continue;let x=r.getItem(k);if(x)try{let E=JSON.parse(x),A=k.substring(l.length);if(b=Math.max(b,E._sys_v!==void 0?E._sys_v:E.v||0),E.e&&Date.now()>E.e){r.removeItem(k),I--;continue}let D=E.d;if(E._enc&&s)D=await Ct(D,s);else if(typeof D=="string"){if(E._b64)try{D=JSON.parse(atob(D))}catch{}else if(D.startsWith("{")||D.startsWith("["))try{D=JSON.parse(D)}catch{}}y[A]=D,a("hydrate",A,!0)}catch(E){a("hydrate",k,!1,String(E));let A=E instanceof Error?E:new Error(String(E));u?u(A,{operation:"hydration",key:k}):p||console.error(`[gState] Hydration failed for "${k}": `,E)}}let B=b<d&&o.migrate?o.migrate(y,b):y;Object.entries(B).forEach(([I,k])=>{let x=S&&k!==null&&typeof k=="object"?$(Q(k),!0):k,E=t(x),A=m.get(I)||0;e.totalSize=e.totalSize-A+E,m.set(I,E),h.set(I,x),_.set(I,1)}),n()}catch(y){let b=y instanceof Error?y:new Error(String(y));u?u(b,{operation:"hydration"}):p||console.error("[gState] Hydration failed: ",b)}};var Ut=(e,t,n)=>{if(e.plugins.size!==0)for(let r of e.plugins.values()){let o=r.hooks?.[t];if(o)try{o(n)}catch(s){let a=s instanceof Error?s:new Error(String(s));e.onError?e.onError(a,{operation:`plugin:${r.name}:${t}`,key:n.key}):e.silent||console.error(`[gState] Plugin "${r.name}" error:`,s)}}},$t=(e,t,n)=>{try{e.plugins.set(t.name,t),t.hooks?.onInstall?.({store:n})}catch(r){let o=r instanceof Error?r:new Error(String(r));e.onError?e.onError(o,{operation:"plugin:install",key:t.name}):e.silent||console.error(`[gState] Failed to install plugin "${t.name}": `,r)}};var pn={local:()=>typeof window<"u"?window.localStorage:null,session:()=>typeof window<"u"?window.sessionStorage:null,memory:()=>{let e=new Map;return{getItem:t=>e.get(t)||null,setItem:(t,n)=>e.set(t,n),removeItem:t=>e.delete(t),key:t=>Array.from(e.keys())[t]||null,get length(){return e.size}}}},X=e=>{let t=new Map,n=new Map,r=new Map,o=new Set,s=new Map,a=new Set,u=new Map,p=new Map,d=new Map,h=new Map,m=new Map,_=new Map,l=new Map,S=new Map,y=e?.namespace||"gstate",b=e?.silent??!1,B=e?.debounceTime??150,I=e?.version??0,k=e?.storage||pn.local(),x=e?.onError,E=e?.maxObjectSize??0,A=e?.maxTotalSize??0,D=e?.encryptionKey??null,le=e?.validateInput??!0,jt=e?.auditEnabled??!0,Y=e?.userId,fe=e?.immer??!0,Lt=e?.persistByDefault??e?.persistence??e?.persist??!1;e?.accessRules&&e.accessRules.forEach(i=>qe(l,i.pattern,i.permissions));let De=!1,Oe=!1,Te=!1,V=0,J=null,F=null,ze,Bt=new Promise(i=>{ze=i}),Kt=()=>`${y}_`,Ze=()=>({store:t,versions:n,sizes:r,totalSize:V,storage:k,config:e||{},diskQueue:m,encryptionKey:D,audit:W,onError:x,silent:b,debounceTime:B,currentVersion:I}),et=()=>({plugins:h,onError:x,silent:b}),Ve=i=>{if(i==null)return 0;let c=typeof i;if(c==="boolean")return 4;if(c==="number")return 8;if(c==="string")return i.length*2;if(c!=="object")return 0;let f=0,w=[i],P=new WeakSet;for(;w.length>0;){let g=w.pop();if(typeof g=="boolean")f+=4;else if(typeof g=="number")f+=8;else if(typeof g=="string")f+=g.length*2;else if(typeof g=="object"&&g!==null){let v=g;if(P.has(v))continue;if(P.add(v),Array.isArray(v))for(let O=0;O<v.length;O++)w.push(v[O]);else for(let O of Object.keys(v))f+=O.length*2,w.push(v[O])}}return f},K=(i,c)=>{Ut(et(),i,c)},W=(i,c,f,w)=>{jt&&Rt()&&ae&&ae({timestamp:Date.now(),action:i,key:c,userId:Y,success:f,error:w})},tt=i=>{let c=p.get(i);if(!c)return;let f=new Set,w=g=>(f.add(g),p.has(g)?p.get(g).lastValue:C.get(g)),P=c.selector(w);c.deps.forEach(g=>{if(!f.has(g)){let v=d.get(g);v&&(v.delete(i),v.size===0&&d.delete(g))}}),f.forEach(g=>{c.deps.has(g)||(d.has(g)||d.set(g,new Set),d.get(g).add(i))}),c.deps=f,ce(c.lastValue,P)||(c.lastValue=fe&&P!==null&&typeof P=="object"?$(Q(P),!0):P,n.set(i,(n.get(i)||0)+1),Z(i))},Z=i=>{if(i){if(d.has(i)){let w=d.get(i);for(let P of w)tt(P)}let c=u.get(i);if(c){let w=C.get(i);for(let P of c)try{P(w)}catch(g){let v=g instanceof Error?g:new Error(String(g));x?x(v,{operation:"watcher",key:i}):b||console.error(`[gState] Watcher error for "${i}":`,g)}}let f=s.get(i);if(f)for(let w of f)try{w()}catch(P){let g=P instanceof Error?P:new Error(String(P));x?x(g,{operation:"keyListener",key:i}):b||console.error(`[gState] Listener error for "${i}":`,P)}}if(De){Oe=!0;return}for(let c of o)try{c()}catch(f){let w=f instanceof Error?f:new Error(String(f));x?x(w,{operation:"listener"}):b||console.error("[gState] Global listener error: ",f)}},nt=async()=>{Vt(Ze())},de={},C={_setSilently:(i,c)=>{let f=r.get(i)||0,w=fe&&c!==null&&typeof c=="object"?$(Q(c),!0):c,g=(E>0||A>0)&&!1?Ve(w):0;V=V-f+g,r.set(i,g),t.set(i,w),n.set(i,(n.get(i)||0)+1),F=null},_registerMethod:(i,c,f)=>{let w=P=>P==="__proto__"||P==="constructor"||P==="prototype";if(w(i)||w(c)){console.warn("[gState] Refusing to register method with unsafe key:",i,c);return}de[i]||(de[i]={}),de[i][c]=f},set:(i,c,f={})=>{let w=t.get(i),P=fe&&typeof c=="function"?kt(w,c):c;if(le&&!Qe(i))return b||console.warn(`[gState] Invalid key: ${i}`),!1;if(!Ae(l,i,"write",Y))return W("set",i,!1,"RBAC Denied"),b||console.error(`[gState] RBAC Denied for "${i}"`),!1;let g=le?ie(P):P,v=r.get(i)||0;K("onBeforeSet",{key:i,value:g,store:C,version:n.get(i)||0});let O=fe&&g!==null&&typeof g=="object"?$(Q(g),!0):g;if(!ce(w,O)){let ee=(E>0||A>0)&&!1?Ve(O):0;if(E>0&&ee>E){let te=new Error(`Object size (${ee} bytes) exceeds maxObjectSize (${E} bytes)`);x?x(te,{operation:"set",key:i}):b||console.warn(`[gState] ${te.message} for "${i}"`)}if(A>0){let te=V-v+ee;if(te>A){let st=new Error(`Total store size (${te} bytes) exceeds limit (${A} bytes)`);x?x(st,{operation:"set"}):b||console.warn(`[gState] ${st.message}`)}}V=V-v+ee,r.set(i,ee),t.set(i,O),n.set(i,(n.get(i)||0)+1),F=null;let ot=f.persist??Lt;return ot&&(m.set(i,{value:O,options:{...f,persist:ot,encoded:f.encoded||e?.encoded}}),J&&clearTimeout(J),J=setTimeout(nt,B)),K("onSet",{key:i,value:O,store:C,version:n.get(i)}),W("set",i,!0),Z(i),!0}return!1},get:i=>{if(!Ae(l,i,"read",Y))return W("get",i,!1,"RBAC Denied"),null;let c=t.get(i);return K("onGet",{store:C,key:i,value:c}),W("get",i,!0),c},compute:(i,c)=>{try{return p.has(i)||(p.set(i,{selector:c,lastValue:null,deps:new Set}),tt(i)),p.get(i).lastValue}catch(f){let w=f instanceof Error?f:new Error(String(f));return x?x(w,{operation:"compute",key:i}):b||console.error(`[gState] Compute error for "${i}": `,f),null}},watch:(i,c)=>{u.has(i)||u.set(i,new Set);let f=u.get(i);return f.add(c),()=>{f.delete(c),f.size===0&&u.delete(i)}},remove:i=>{if(!Ae(l,i,"delete",Y))return W("delete",i,!1,"RBAC Denied"),!1;let c=t.get(i),f=t.delete(i);return f&&(V-=r.get(i)||0,r.delete(i),K("onRemove",{store:C,key:i,value:c}),F=null),n.set(i,(n.get(i)||0)+1),k&&k.removeItem(`${Kt()}${i}`),W("delete",i,!0),Z(i),f},delete:i=>C.remove(i),deleteAll:()=>{if(Array.from(t.keys()).forEach(i=>C.remove(i)),k){let i=y+"_";for(let c=0;c<(k.length||0);c++){let f=k.key(c);f?.startsWith(i)&&(k.removeItem(f),c--)}}return V=0,r.clear(),F=null,!0},list:()=>Object.fromEntries(t.entries()),use:i=>{a.add(i)},transaction:i=>{De=!0,K("onTransaction",{store:C,key:"START"});try{i()}finally{De=!1,K("onTransaction",{store:C,key:"END"}),Oe&&(Oe=!1,Z())}},destroy:()=>{J&&(clearTimeout(J),J=null),m.clear(),typeof window<"u"&&window.removeEventListener("beforeunload",rt),K("onDestroy",{store:C}),o.clear(),s.clear(),u.clear(),p.clear(),d.clear(),h.clear(),t.clear(),r.clear(),V=0,l.clear(),S.clear(),n.clear(),_.clear(),a.clear()},_addPlugin:i=>{$t(et(),i,C)},_removePlugin:i=>{h.delete(i)},_subscribe:(i,c)=>{if(c){s.has(c)||s.set(c,new Set);let f=s.get(c);return f.add(i),()=>{f.delete(i),f.size===0&&s.delete(c)}}return o.add(i),()=>o.delete(i)},_getVersion:i=>n.get(i)??0,addAccessRule:(i,c)=>qe(l,i,c),hasPermission:(i,c,f)=>{if(l.size===0)return!0;for(let[w,P]of l){let g;if(typeof w=="function")g=w(i,f);else try{let v=_.get(w);v||(v=new RegExp(w),_.set(w,v)),g=v.test(i)}catch{continue}if(g)return P.includes(c)||P.includes("admin")}return!1},recordConsent:(i,c,f)=>Xe(S,i,c,f),hasConsent:(i,c)=>It(S,i,c),getConsents:i=>Mt(S,i),revokeConsent:(i,c)=>At(S,i,c),exportUserData:i=>Dt(S,i),deleteUserData:i=>Ot(S,i),getSnapshot:()=>(F||(F=Object.fromEntries(t.entries())),F),get plugins(){return de},get isReady(){return Te},get namespace(){return y},get userId(){return Y},whenReady:()=>Bt};["addAccessRule","recordConsent","hasConsent","getConsents","revokeConsent","exportUserData","deleteUserData"].forEach(i=>{let c=C[i];c&&C._registerMethod("security",i,c)});let rt=()=>{m.size>0&&nt()};return typeof window<"u"&&window.addEventListener("beforeunload",rt),k?Nt(Ze(),i=>(E>0||A>0)&&!1?Ve(i):0,()=>{Te=!0,F=null,ze(),Z()}).then(()=>{}):(Te=!0,ze()),C};import{useSyncExternalStore as Ft,useDebugValue as gn,useMemo as Ye,useCallback as Me}from"react";var L=null,yn=e=>{L&&!e?.namespace&&(e?.silent||console.warn("[gState] Store already exists. Pass a unique namespace to create additional stores."));let t=X(e);return L=t,t},Sn=()=>{L&&(L.destroy(),L=null)},hn=e=>{let t=e||L,n=Ye(()=>r=>t?t._subscribe(r):()=>{},[t]);return Ft(n,()=>t?t.isReady:!1,()=>!0)},z=()=>L;function ue(e,t){let n=Ye(()=>t||L,[t]),r=Ye(()=>{let l=()=>{},S=()=>!1,y=()=>null;return{set:S,get:y,remove:S,delete:S,deleteAll:S,list:()=>({}),compute:y,watch:()=>()=>{},use:l,transaction:l,destroy:l,_subscribe:()=>()=>{},_setSilently:l,_registerMethod:l,_addPlugin:l,_removePlugin:l,_getVersion:()=>0,get isReady(){return!1},whenReady:()=>Promise.resolve(),get plugins(){return{}},getSnapshot:()=>({}),get namespace(){return"ghost"},get userId(){}}},[]),o=n||r,s=typeof e=="function",a=s?null:e,u=s?e:null,p=Me(l=>s?o._subscribe(l):o._subscribe(l,a),[o,s,a]),d=Me(()=>s?u(o.getSnapshot()):o.get(a)??void 0,[o,s,a,u]),h=Me(()=>{if(s)try{return u({})}catch{return}else return},[u,s]),m=Ft(p,d,h),_=Me((l,S)=>s?!1:o.set(a,l,S),[o,s,a]);return gn(m,l=>s?`Selector: ${JSON.stringify(l)}`:`${a}: ${JSON.stringify(l)}`),s?m:[m,_]}var mn=(e,t)=>{let n=t?.key||"async_data",r=t?.store||X({namespace:`async_${n}`,silent:!0});return r.get(n)==null&&r.set(n,{data:null,loading:!1,error:null,updatedAt:null}),Object.assign(r,{execute:async()=>{let s=r.get(n);r.set(n,{...s||{data:null,loading:!1,error:null,updatedAt:null},loading:!0,error:null}),"whenReady"in r&&!r.isReady&&await r.whenReady();try{let a=await e(),u=r.get(n);r.set(n,{...u||{data:null,loading:!1,error:null,updatedAt:null},data:a,loading:!1,updatedAt:Date.now()},{persist:t?.persist})}catch(a){let u=r.get(n);r.set(n,{...u||{data:null,loading:!1,error:null,updatedAt:null},error:a instanceof Error?a:new Error(String(a)),loading:!1})}}})};var _n=()=>({name:"gstate-immer",hooks:{onInstall:({store:e})=>{e._registerMethod("immer","setWithProduce",((t,n)=>e.set(t,n)))}}});var wn=e=>{let t=[],n=-1,r=!1,o=e?.limit||50;return{name:"gstate-undo-redo",hooks:{onInstall:({store:s})=>{t.push(s.list()),n=0,s._registerMethod("undoRedo","undo",()=>{if(n>0){r=!0,n--;let a=t[n];return a?(Object.entries(a).forEach(([u,p])=>{s._setSilently(u,p)}),r=!1,!0):!1}return!1}),s._registerMethod("undoRedo","redo",()=>{if(n<t.length-1){r=!0,n++;let a=t[n];return a?(Object.entries(a).forEach(([u,p])=>{s._setSilently(u,p)}),r=!1,!0):!1}return!1}),s._registerMethod("undoRedo","canUndo",()=>n>0),s._registerMethod("undoRedo","canRedo",()=>n<t.length-1)},onSet:({store:s})=>{r||(n<t.length-1&&(t=t.slice(0,n+1)),t.push(s.list()),t.length>o?t.shift():n++)}}}};var bn=e=>({name:"gstate-schema",hooks:{onSet:({key:t,value:n})=>{if(!t)return;let r=e[t];if(r){let o=r(n);if(o!==!0)throw new Error(`[Schema Error] Validation failed for key "${t}": ${o===!1?"Invalid type":o}`)}}}});var Pn=e=>{let r=globalThis.__REDUX_DEVTOOLS_EXTENSION__;if(!r?.connect)return{name:"gstate-devtools-noop",hooks:{}};let o=null;return{name:"gstate-devtools",hooks:{onInstall:({store:s})=>{o=r.connect({name:e?.name||"Magnetar Store"}),o.init(s.list())},onSet:({key:s,store:a})=>{!s||!o||o.send(`SET_${s.toUpperCase()}`,a.list())},onRemove:({key:s,store:a})=>{!s||!o||o.send(`REMOVE_${s.toUpperCase()}`,a.list())}}}};var En=()=>{let e=new Map;return{name:"gstate-snapshot",hooks:{onInstall:({store:t})=>{t._registerMethod("snapshot","takeSnapshot",(n=>{e.set(n,t.list())})),t._registerMethod("snapshot","restoreSnapshot",(n=>{let r=e.get(n);return r?(t.transaction(()=>{Object.entries(r).forEach(([o,s])=>{t.set(o,s)})}),!0):!1})),t._registerMethod("snapshot","listSnapshots",(()=>Array.from(e.keys()))),t._registerMethod("snapshot","deleteSnapshot",(n=>e.delete(n))),t._registerMethod("snapshot","clearSnapshots",(()=>e.clear()))}}}};var kn=e=>({name:"gstate-guard",hooks:{onBeforeSet:({key:t,value:n,store:r})=>{if(!t)return;let o=e[t];if(o){let s=o(n)}}}});var vn=e=>({name:"gstate-analytics",hooks:{onSet:({key:t,value:n})=>{t&&(!e.keys||e.keys.includes(t))&&e.provider({key:t,value:n,action:"SET"})},onRemove:({key:t})=>{t&&(!e.keys||e.keys.includes(t))&&e.provider({key:t,value:null,action:"REMOVE"})}}});var xn=e=>{let t=new BroadcastChannel(e?.channelName||"gstate_sync"),n=!1;return{name:"gstate-sync",hooks:{onInstall:({store:r})=>{t.onmessage=o=>{let{key:s,value:a,action:u}=o.data;s&&(n=!0,u==="REMOVE"?r.remove(s):r.set(s,a),n=!1)}},onSet:({key:r,value:o})=>{!r||n||t.postMessage({key:r,value:o,action:"SET"})},onRemove:({key:r})=>{!r||n||t.postMessage({key:r,action:"REMOVE"})},onDestroy:()=>{t.close()}}}};var Cn=()=>({name:"gstate-debug-noop",hooks:{}});var Rn=(e={})=>{let t=e.dbName||"rgs-db",n=e.storeName||"states",r=e.version||1,o=null,s=()=>new Promise((d,h)=>{if(o)return d(o);let m=indexedDB.open(t,r);m.onerror=()=>h(m.error),m.onsuccess=()=>{o=m.result,d(o)},m.onupgradeneeded=_=>{let l=_.target.result;l.objectStoreNames.contains(n)||l.createObjectStore(n)}}),a=async(d,h)=>{let m=await s();return new Promise((_,l)=>{let b=m.transaction(n,"readwrite").objectStore(n).put(h,d);b.onsuccess=()=>_(),b.onerror=()=>l(b.error)})},u=async d=>{let h=await s();return new Promise((m,_)=>{let y=h.transaction(n,"readonly").objectStore(n).get(d);y.onsuccess=()=>m(y.result),y.onerror=()=>_(y.error)})},p=async d=>{let h=await s();return new Promise((m,_)=>{let y=h.transaction(n,"readwrite").objectStore(n).delete(d);y.onsuccess=()=>m(),y.onerror=()=>_(y.error)})};return{name:"indexedDB",hooks:{onInstall:({store:d})=>{d._registerMethod("indexedDB","clear",async()=>{(await s()).transaction(n,"readwrite").objectStore(n).clear()})},onInit:async({store:d})=>{let l=(await s()).transaction(n,"readonly").objectStore(n).getAllKeys();l.onsuccess=async()=>{let S=l.result,y=d.namespace+"_";for(let b of S)if(b.startsWith(y)){let B=await u(b);if(B){let I=b.substring(y.length);d._setSilently(I,B.d)}}}},onSet:async({key:d,value:h,store:m})=>{if(!d)return;let _=m.namespace+"_",l={d:h,t:Date.now(),v:m._getVersion?.(d)||1};await a(`${_}${d}`,l)},onRemove:async({key:d,store:h})=>{if(!d)return;let m=h.namespace+"_";await p(`${m}${d}`)}}}};var In=e=>{let{adapter:t,autoSyncInterval:n}=e,r=new Map,o={lastSyncTimestamp:null,totalKeysSynced:0,totalBytesSynced:0,syncCount:0,lastDuration:0,errors:0},s=null;return{name:"cloudSync",hooks:{onInstall:({store:a})=>{a._registerMethod("cloudSync","sync",async()=>{let u=performance.now(),p={},d=0;try{let h=a.list(),m=Object.keys(h);for(let l of m){let S=a._getVersion?.(l)||0,y=r.get(l)||0;if(S>y){let b=h[l];p[l]=b,d+=JSON.stringify(b).length,r.set(l,S)}}if(Object.keys(p).length===0)return{status:"no-change",stats:o};if(await t.save(p))return o.lastSyncTimestamp=Date.now(),o.totalKeysSynced+=Object.keys(p).length,o.totalBytesSynced+=d,o.syncCount++,o.lastDuration=performance.now()-u,e.onSync&&e.onSync(o),{status:"success",stats:o};throw new Error(`Adapter ${t.name} failed to save.`)}catch(h){return o.errors++,console.error(`[gState] Cloud Sync Failed (${t.name}):`,h),{status:"error",error:String(h),stats:o}}}),a._registerMethod("cloudSync","getStats",()=>o),n&&n>0&&(s=setInterval(()=>{let p=a.plugins.cloudSync;p&&p.sync()},n))},onDestroy:()=>{s&&clearInterval(s)}}}},An=(e,t)=>({name:"MongoDB-Atlas",save:async n=>(await fetch(`${e}/action/updateOne`,{method:"POST",headers:{"Content-Type":"application/json","api-key":t},body:JSON.stringify({dataSource:"Cluster0",database:"rgs_cloud",collection:"user_states",filter:{id:"global_state"},update:{$set:{data:n,updatedAt:Date.now()}},upsert:!0})})).ok}),Mn=(e,t)=>({name:"Firebase-Firestore",save:async n=>{try{return((...s)=>{})("[Mock] Firestore Syncing:",n),!0}catch{return!1}}}),Dn=(e,t)=>({name:"SQL-REST-API",save:async n=>(await fetch(e,{method:"PATCH",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(n)})).ok});var ir=e=>({name:"gstate-logger",hooks:{onSet:({key:t,value:n,version:r})=>{let o=new Date().toLocaleTimeString(),s=`[gState] SET: ${t} (v${r}) @ ${o}`;e?.collapsed?console.groupCollapsed(s):console.group(s),console.info("%c Value:","color: #4CAF50; font-weight: bold;",n),console.groupEnd()},onRemove:({key:t})=>{console.warn(`[gState] REMOVED: ${t}`)},onTransaction:({key:t})=>{t==="START"?console.group("\u2500\u2500 TRANSACTION START \u2500\u2500"):console.groupEnd()}}});var br=(e,t)=>{let r=X(typeof t=="string"?{namespace:t}:t);e&&Object.entries(e).forEach(([s,a])=>{r.get(s)===null&&r._setSilently(s,a)});let o=s=>ue(s,r);return typeof window<"u"&&(window.gState=r,window.rgs=r),Object.assign(o,r)};var Pr=(e,t)=>z()?.addAccessRule(e,t),Er=(e,t,n)=>z()?.hasPermission(e,t,n)??!0,kr=(e,t,n)=>{let r=z();if(!r)throw new Error("[gState] recordConsent failed: No store found. call initState() first.");return r.recordConsent(e,t,n)},vr=(e,t)=>z()?.hasConsent(e,t)??!1,xr=e=>z()?.getConsents(e)??[],Cr=(e,t)=>z()?.revokeConsent(e,t),Rr=e=>{let t=z();if(!t)throw new Error("[gState] exportUserData failed: No store found.");return t.exportUserData(e)},Ir=e=>{let t=z();if(!t)throw new Error("[gState] deleteUserData failed: No store found.");return t.deleteUserData(e)},Ar=()=>{},Mr=()=>{};export{Pr as addAccessRule,vn as analyticsPlugin,Ar as clearAccessRules,Mr as clearAllConsents,In as cloudSyncPlugin,mn as createAsyncStore,Mn as createFirestoreAdapter,An as createMongoAdapter,Dn as createSqlRestAdapter,X as createStore,Cn as debugPlugin,Ir as deleteUserData,Sn as destroyState,Pn as devToolsPlugin,cn as exportKey,Rr as exportUserData,an as generateEncryptionKey,xr as getConsents,z as getStore,br as gstate,kn as guardPlugin,vr as hasConsent,Er as hasPermission,_n as immerPlugin,un as importKey,Rn as indexedDBPlugin,yn as initState,vt as isCryptoAvailable,ae as logAudit,ir as loggerPlugin,kr as recordConsent,Cr as revokeConsent,ie as sanitizeValue,bn as schemaPlugin,ln as setAuditLogger,En as snapshotPlugin,xn as syncPlugin,wn as undoRedoPlugin,ue as useGState,hn as useIsStoreReady,ue as useSimpleState,ue as useStore,Qe as validateKey};
|
|
1
|
+
import{produce as ht,freeze as Ne}from"immer";var D=typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof crypto.subtle.generateKey=="function",V=async()=>{if(!D)throw new Error("Web Crypto API not available");let t=await crypto.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),e=crypto.getRandomValues(new Uint8Array(12));return{key:t,iv:e}},j=async t=>{let e=await crypto.subtle.exportKey("raw",t.key);return{key:btoa(String.fromCharCode(...new Uint8Array(e))),iv:btoa(String.fromCharCode(...t.iv))}},$=async(t,e)=>{let n=Uint8Array.from(atob(t),i=>i.charCodeAt(0)),r=Uint8Array.from(atob(e),i=>i.charCodeAt(0));return{key:await crypto.subtle.importKey("raw",n,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),iv:r}},Qe=async(t,e)=>{let n=new TextEncoder,r=n.encode(JSON.stringify(t)),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:e.iv},e.key,r),i=new Uint8Array(e.iv.length+s.byteLength);return i.set(e.iv),i.set(new Uint8Array(s),e.iv.length),btoa(String.fromCharCode(...i))},He=async(t,e)=>{let n=Uint8Array.from(atob(t),a=>a.charCodeAt(0)),r=n.slice(0,12),s=n.slice(12),i=await crypto.subtle.decrypt({name:"AES-GCM",iv:r},e.key,s);return JSON.parse(new TextDecoder().decode(i))},Ie=null,z=t=>{Ie=t},Ge=()=>Ie!==null,P=t=>{Ie&&Ie(t)},$e=(t,e,n)=>{t.set(e instanceof RegExp?e.source:e,n)},Ae=(t,e,n,r)=>{if(t.size===0)return!0;for(let[s,i]of t){let a;if(typeof s=="function")a=s(e,r);else try{a=new RegExp(s).test(e)}catch{continue}if(a)return i.includes(n)||i.includes("admin")}return!1},R=t=>{if(typeof t=="string"){let e=t.replace(/&#[xX]?[0-9a-fA-F]+;?/g,r=>{let s=r.match(/&#x([0-9a-fA-F]+);?/i);if(s&&s[1])return String.fromCharCode(parseInt(s[1],16));let i=r.match(/&#([0-9]+);?/);return i&&i[1]?String.fromCharCode(parseInt(i[1],10)):""});try{e=decodeURIComponent(e)}catch{}return e.replace(/\b(javascript|vbscript|data:text\/html|about:blank|chrome:)/gi,"[SEC-REMOVED]").replace(/<script\b[^>]*>[\s\S]*?<\s*\/\s*script\b[^>]*>/gi,"[SEC-REMOVED]").replace(/on\w+\s*=/gi,"[SEC-REMOVED]=").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,"[SEC-REMOVED]").replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi,"[SEC-REMOVED]").replace(/<embed\b[^<]*(?:(?!<\/embed>)<[^<]*)*<\/embed>/gi,"[SEC-REMOVED]").replace(/<svg\b[^<]*(?:(?!<\/svg>)<[^<]*)*<\/svg>/gi,"[SEC-REMOVED]").replace(/<form\b[^<]*(?:(?!<\/form>)<[^<]*)*<\/form>/gi,"[SEC-REMOVED]").replace(/<base\b[^<]*(?:(?!<\/base>)<[^<]*)*<\/base>/gi,"[SEC-REMOVED]").replace(/<link\b[^<]*(?:(?!<\/link>)<[^<]*)*<\/link>/gi,"[SEC-REMOVED]").replace(/<meta\b[^<]*(?:(?!<\/meta>)<[^<]*)*<\/meta>/gi,"[SEC-REMOVED]").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,"[SEC-REMOVED]")}if(t&&typeof t=="object"&&!Array.isArray(t)){if(Object.getPrototypeOf(t)===Object.prototype){let e={};for(let[n,r]of Object.entries(t))e[n]=R(r);return e}return t}return Array.isArray(t)?t.map(e=>R(e)):t},A=t=>/^[a-zA-Z0-9_.-]+$/.test(t)&&t.length<=256,ze=(t,e,n,r)=>{let s={id:crypto.randomUUID(),purpose:n,granted:r,timestamp:Date.now()},i=t.get(e)||[];return i.push(s),t.set(e,i),P({timestamp:Date.now(),action:"set",key:`consent:${n}`,userId:e,success:!0}),s},Xe=(t,e,n)=>{let r=t.get(e);if(!r)return!1;for(let s=r.length-1;s>=0;s--){let i=r[s];if(i&&i.purpose===n)return i.granted}return!1},Ze=(t,e,n)=>ze(t,e,n,!1),Ye=(t,e)=>t.get(e)||[],et=(t,e)=>({userId:e,exportedAt:Date.now(),consents:t.get(e)||[]}),tt=(t,e)=>{let n=t.get(e)?.length||0;return t.delete(e),{success:!0,deletedConsents:n}};var ye=t=>{if(t===null||typeof t!="object")return t;if(typeof structuredClone=="function")try{return structuredClone(t)}catch{}let e=new WeakMap,n=r=>{if(r===null||typeof r!="object"||typeof r=="function")return r;if(e.has(r))return e.get(r);if(r instanceof Date)return new Date(r.getTime());if(r instanceof RegExp)return new RegExp(r.source,r.flags);if(r instanceof Map){let a=new Map;return e.set(r,a),r.forEach((l,f)=>a.set(n(f),n(l))),a}if(r instanceof Set){let a=new Set;return e.set(r,a),r.forEach(l=>a.add(n(l))),a}let s=Array.isArray(r)?[]:Object.create(Object.getPrototypeOf(r));e.set(r,s);let i=[...Object.keys(r),...Object.getOwnPropertySymbols(r)];for(let a of i)s[a]=n(r[a]);return s};return n(t)},xe=(t,e)=>{if(t===e)return!0;if(t===null||e===null||typeof t!="object"||typeof e!="object")return t===e;if(Array.isArray(t)&&Array.isArray(e)){if(t.length!==e.length)return!1;for(let s=0;s<t.length;s++)if(!xe(t[s],e[s]))return!1;return!0}let n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(let s=0;s<n.length;s++){let i=n[s];if(!(i in e)||!xe(t[i],e[i]))return!1}return!0};import{freeze as yt}from"immer";var rt=t=>`${t}_`,st=async t=>{if(!t.storage)return;let{store:e,config:n,diskQueue:r,storage:s,encryptionKey:i,audit:a,onError:l,silent:f,currentVersion:p}=t,b=rt(n.namespace||"gstate");try{let w={};e.forEach((h,k)=>{w[k]=h});let u,S=n?.encoded;S?u=btoa(JSON.stringify(w)):u=JSON.stringify(w),s.setItem(b.replace("_",""),JSON.stringify({v:1,t:Date.now(),e:null,d:u,_sys_v:p,_b64:S?!0:void 0})),a("set","FULL_STATE",!0)}catch(w){let u=w instanceof Error?w:new Error(String(w));l?l(u,{operation:"persist",key:"FULL_STATE"}):f||console.error("[gState] Persist failed: ",u)}let m=Array.from(r.entries());r.clear();for(let[w,u]of m)try{let S=u.value,h=u.options.encoded||u.options.secure;if(u.options.encrypted){if(!i)throw new Error(`Encryption key missing for "${w}"`);S=await Qe(u.value,i)}else h?S=btoa(JSON.stringify(u.value)):typeof u.value=="object"&&u.value!==null&&(S=JSON.stringify(u.value));s.setItem(`${b}${w}`,JSON.stringify({v:t.versions.get(w)||1,t:Date.now(),e:u.options.ttl?Date.now()+u.options.ttl:null,d:S,_sys_v:p,_enc:u.options.encrypted?!0:void 0,_b64:h?!0:void 0})),a("set",w,!0)}catch(S){let h=S instanceof Error?S:new Error(String(S));l?l(h,{operation:"persist",key:w}):f||console.error("[gState] Persist failed: ",h)}},ot=async(t,e,n)=>{let{storage:r,config:s,encryptionKey:i,audit:a,onError:l,silent:f,currentVersion:p,store:b,sizes:m,versions:w}=t,u=rt(s.namespace||"gstate"),S=s.immer??!0;if(r)try{let h={},k=0;for(let ae=0;ae<(r.length||0);ae++){let I=r.key(ae);if(!I||!I.startsWith(u))continue;let M=r.getItem(I);if(M)try{let _=JSON.parse(M),ce=I.substring(u.length);if(k=Math.max(k,_._sys_v!==void 0?_._sys_v:_.v||0),_.e&&Date.now()>_.e){r.removeItem(I),ae--;continue}let ue=_.d;if(_._enc&&i)ue=await He(ue,i);else if(typeof ue=="string"){if(_._b64)try{ue=JSON.parse(atob(ue))}catch{}else if(ue.startsWith("{")||ue.startsWith("["))try{ue=JSON.parse(ue)}catch{}}h[ce]=ue,a("hydrate",ce,!0)}catch(_){a("hydrate",I,!1,String(_));let ce=_ instanceof Error?_:new Error(String(_));l?l(ce,{operation:"hydration",key:I}):f||console.error(`[gState] Hydration failed for "${I}": `,_)}}let Se=k<p&&s.migrate?s.migrate(h,k):h;Object.entries(Se).forEach(([ae,I])=>{let M=S&&I!==null&&typeof I=="object"?yt(ye(I),!0):I,_=e(M),ce=m.get(ae)||0;t.totalSize=t.totalSize-ce+_,m.set(ae,_),b.set(ae,M),w.set(ae,1)}),n()}catch(h){let k=h instanceof Error?h:new Error(String(h));l?l(k,{operation:"hydration"}):f||console.error("[gState] Hydration failed: ",k)}};var it=(t,e,n)=>{if(t.plugins.size!==0)for(let r of t.plugins.values()){let s=r.hooks?.[e];if(s)try{s(n)}catch(i){let a=i instanceof Error?i:new Error(String(i));t.onError?t.onError(a,{operation:`plugin:${r.name}:${e}`,key:n.key}):t.silent||console.error(`[gState] Plugin "${r.name}" error:`,i)}}},at=(t,e,n)=>{try{t.plugins.set(e.name,e),e.hooks?.onInstall?.({store:n})}catch(r){let s=r instanceof Error?r:new Error(String(r));t.onError?t.onError(s,{operation:"plugin:install",key:e.name}):t.silent||console.error(`[gState] Failed to install plugin "${e.name}": `,r)}};var E=class{store;config;pendingQueue=new Map;remoteVersions=new Map;syncTimer=null;onlineStatusListeners=new Set;syncStateListeners=new Set;_isOnline=!0;_isSyncing=!1;constructor(e,n){this.store=e,this.config={endpoint:n.endpoint,authToken:n.authToken||"",strategy:n.strategy||"last-write-wins",autoSyncInterval:n.autoSyncInterval??3e4,syncOnReconnect:n.syncOnReconnect??!0,debounceTime:n.debounceTime??1e3,fetch:n.fetch||fetch,onSync:n.onSync||(()=>{}),onConflict:n.onConflict||(()=>({action:"accept-local"})),maxRetries:n.maxRetries??3},this._isOnline=typeof navigator<"u"?navigator.onLine:!0,this._setupOnlineListener(),this._setupStoreListener(),this.config.autoSyncInterval>0&&this._startAutoSync()}_setupOnlineListener(){typeof window>"u"||(window.addEventListener("online",()=>{this._isOnline=!0,this._notifyOnlineChange(!0),this.config.syncOnReconnect&&this.sync()}),window.addEventListener("offline",()=>{this._isOnline=!1,this._notifyOnlineChange(!1)}))}_setupStoreListener(){this.store._subscribe(()=>{})}_startAutoSync(){setInterval(()=>{this._isOnline&&!this._isSyncing&&this.pendingQueue.size>0&&this.sync()},this.config.autoSyncInterval)}_notifyOnlineChange(e){this.onlineStatusListeners.forEach(n=>n(e)),this._notifyStateChange()}_notifyStateChange(){let e=this.getState();this.syncStateListeners.forEach(n=>n(e))}queueChange(e,n){let r=this.store._getVersion(e)||1;this.pendingQueue.set(e,{key:e,value:ye(n),timestamp:Date.now(),version:r}),this._notifyStateChange(),this.syncTimer&&clearTimeout(this.syncTimer),this.syncTimer=setTimeout(()=>{this._isOnline&&this.sync()},this.config.debounceTime)}async sync(){if(this._isSyncing)return{success:!1,syncedKeys:[],conflicts:[],errors:["Sync already in progress"],timestamp:Date.now(),duration:0};this._isSyncing=!0,this._notifyStateChange();let e=Date.now(),n=[],r=[],s=[];try{let i=Array.from(this.pendingQueue.values());if(i.length===0)return this._isSyncing=!1,this._notifyStateChange(),{success:!0,syncedKeys:[],conflicts:[],errors:[],timestamp:Date.now(),duration:Date.now()-e};await this._fetchRemoteVersions(i.map(l=>l.key));for(let l of i)try{let f=this.remoteVersions.get(l.key);if(!f)await this._pushChange(l),n.push(l.key),this.pendingQueue.delete(l.key);else if(f.version>=l.version){let p={key:l.key,localValue:l.value,remoteValue:f.value,localVersion:l.version,remoteVersion:f.version,timestamp:l.timestamp};r.push(p);let b=this.config.onConflict(p);await this._resolveConflict(l,f,b),n.push(l.key),this.pendingQueue.delete(l.key)}else await this._pushChange(l),n.push(l.key),this.pendingQueue.delete(l.key)}catch(f){s.push(`Failed to sync "${l.key}": ${f}`)}let a={success:s.length===0,syncedKeys:n,conflicts:r,errors:s,timestamp:Date.now(),duration:Date.now()-e};return this.config.onSync(a),a}catch(i){let a=`Sync failed: ${i}`;return s.push(a),{success:!1,syncedKeys:n,conflicts:r,errors:s,timestamp:Date.now(),duration:Date.now()-e}}finally{this._isSyncing=!1,this._notifyStateChange()}}async _fetchRemoteVersions(e){try{let n=await this.config.fetch(`${this.config.endpoint}/versions`,{method:"POST",headers:{"Content-Type":"application/json",...this.config.authToken&&{Authorization:`Bearer ${this.config.authToken}`}},body:JSON.stringify({keys:e})});if(n.ok){let r=await n.json();if(r.versions)for(let[s,i]of Object.entries(r.versions))this.remoteVersions.set(s,i)}}catch(n){console.warn("[SyncEngine] Failed to fetch remote versions:",n)}}async _pushChange(e){let n=0;for(;n<this.config.maxRetries;)try{let r=await this.config.fetch(`${this.config.endpoint}/sync`,{method:"POST",headers:{"Content-Type":"application/json",...this.config.authToken&&{Authorization:`Bearer ${this.config.authToken}`}},body:JSON.stringify({key:e.key,value:e.value,version:e.version,timestamp:e.timestamp})});if(r.ok){let s=await r.json();s.version&&this.remoteVersions.set(e.key,{version:s.version,timestamp:s.timestamp||Date.now(),value:e.value});return}n++}catch(r){if(n++,n>=this.config.maxRetries)throw r}}async _resolveConflict(e,n,r){switch(r.action){case"accept-local":await this._pushChange({...e,version:n.version+1,timestamp:Date.now()});break;case"accept-remote":this.store.set(e.key,n.value);break;case"merge":this.store.set(e.key,r.value),await this._pushChange({key:e.key,value:r.value,version:Math.max(e.version,n.version)+1,timestamp:Date.now()});break;case"discard":break}}getState(){return{isOnline:this._isOnline,isSyncing:this._isSyncing,lastSyncTimestamp:null,pendingChanges:this.pendingQueue.size,conflicts:0}}onOnlineChange(e){return this.onlineStatusListeners.add(e),()=>this.onlineStatusListeners.delete(e)}onStateChange(e){return this.syncStateListeners.add(e),()=>this.syncStateListeners.delete(e)}async flush(){return this.sync()}destroy(){this.syncTimer&&clearTimeout(this.syncTimer),this.pendingQueue.clear(),this.onlineStatusListeners.clear(),this.syncStateListeners.clear()}},N=(t,e)=>new E(t,e);var wt={local:()=>typeof window<"u"?window.localStorage:null,session:()=>typeof window<"u"?window.sessionStorage:null,memory:()=>{let t=new Map;return{getItem:e=>t.get(e)||null,setItem:(e,n)=>t.set(e,n),removeItem:e=>t.delete(e),key:e=>Array.from(t.keys())[e]||null,get length(){return t.size}}}},T=t=>{let e=new Map,n=new Map,r=new Map,s=new Set,i=new Map,a=new Set,l=new Map,f=new Map,p=new Map,b=new Map,m=new Map,w=new Map,u=new Map,S=new Map,h=t?.namespace||"gstate",k=t?.silent??!1,Se=t?.debounceTime??150,ae=t?.version??0,I=t?.storage||wt.local(),M=t?.onError,_=t?.maxObjectSize??0,ce=t?.maxTotalSize??0,ue=t?.encryptionKey??null,_e=t?.validateInput??!0,dt=t?.auditEnabled??!0,be=t?.userId,Re=t?.immer??!0,gt=t?.persistByDefault??t?.persistence??t?.persist??!1;t?.accessRules&&t.accessRules.forEach(o=>$e(u,o.pattern,o.permissions));let Oe=!1,De=!1,Me=!1,ge=0,we=null,fe=null,Ve,pt=new Promise(o=>{Ve=o}),ft=()=>`${h}_`,Ue=()=>({store:e,versions:n,sizes:r,totalSize:ge,storage:I,config:t||{},diskQueue:m,encryptionKey:ue,audit:he,onError:M,silent:k,debounceTime:Se,currentVersion:ae}),Ke=()=>({plugins:b,onError:M,silent:k}),je=o=>{if(o==null)return 0;let c=typeof o;if(c==="boolean")return 4;if(c==="number")return 8;if(c==="string")return o.length*2;if(c!=="object")return 0;let g=0,v=[o],x=new WeakSet;for(;v.length>0;){let y=v.pop();if(typeof y=="boolean")g+=4;else if(typeof y=="number")g+=8;else if(typeof y=="string")g+=y.length*2;else if(typeof y=="object"&&y!==null){let O=y;if(x.has(O))continue;if(x.add(O),Array.isArray(O))for(let le=0;le<O.length;le++)v.push(O[le]);else for(let le of Object.keys(O))g+=le.length*2,v.push(O[le])}}return g},me=(o,c)=>{it(Ke(),o,c)},he=(o,c,g,v)=>{dt&&Ge()&&P&&P({timestamp:Date.now(),action:o,key:c,userId:be,success:g,error:v})},Be=o=>{let c=f.get(o);if(!c)return;let g=new Set,v=y=>(g.add(y),f.has(y)?f.get(y).lastValue:Z.get(y)),x=c.selector(v);c.deps.forEach(y=>{if(!g.has(y)){let O=p.get(y);O&&(O.delete(o),O.size===0&&p.delete(y))}}),g.forEach(y=>{c.deps.has(y)||(p.has(y)||p.set(y,new Set),p.get(y).add(o))}),c.deps=g,xe(c.lastValue,x)||(c.lastValue=Re&&x!==null&&typeof x=="object"?Ne(ye(x),!0):x,n.set(o,(n.get(o)||0)+1),ve(o))},ve=o=>{if(o){if(p.has(o)){let v=p.get(o);for(let x of v)Be(x)}let c=l.get(o);if(c){let v=Z.get(o);for(let x of c)try{x(v)}catch(y){let O=y instanceof Error?y:new Error(String(y));M?M(O,{operation:"watcher",key:o}):k||console.error(`[gState] Watcher error for "${o}":`,y)}}let g=i.get(o);if(g)for(let v of g)try{v()}catch(x){let y=x instanceof Error?x:new Error(String(x));M?M(y,{operation:"keyListener",key:o}):k||console.error(`[gState] Listener error for "${o}":`,x)}}if(Oe){De=!0;return}for(let c of s)try{c()}catch(g){let v=g instanceof Error?g:new Error(String(g));M?M(v,{operation:"listener"}):k||console.error("[gState] Global listener error: ",g)}},Fe=async()=>{st(Ue())},Pe={},Z={_setSilently:(o,c)=>{let g=r.get(o)||0,v=Re&&c!==null&&typeof c=="object"?Ne(ye(c),!0):c,y=(_>0||ce>0)&&!1?je(v):0;ge=ge-g+y,r.set(o,y),e.set(o,v),n.set(o,(n.get(o)||0)+1),fe=null},_registerMethod:(o,c,g)=>{let v=x=>x==="__proto__"||x==="constructor"||x==="prototype";if(v(o)||v(c)){console.warn("[gState] Refusing to register method with unsafe key:",o,c);return}Pe[o]||(Pe[o]={}),Pe[o][c]=g},set:(o,c,g={})=>{let v=e.get(o),x=Re&&typeof c=="function"?ht(v,c):c;if(_e&&!A(o))return k||console.warn(`[gState] Invalid key: ${o}`),!1;if(!Ae(u,o,"write",be))return he("set",o,!1,"RBAC Denied"),k||console.error(`[gState] RBAC Denied for "${o}"`),!1;let y=_e?R(x):x,O=r.get(o)||0;me("onBeforeSet",{key:o,value:y,store:Z,version:n.get(o)||0});let le=Re&&y!==null&&typeof y=="object"?Ne(ye(y),!0):y;if(!xe(v,le)){let ke=(_>0||ce>0)&&!1?je(le):0;if(_>0&&ke>_){let Ce=new Error(`Object size (${ke} bytes) exceeds maxObjectSize (${_} bytes)`);M?M(Ce,{operation:"set",key:o}):k||console.warn(`[gState] ${Ce.message} for "${o}"`)}if(ce>0){let Ce=ge-O+ke;if(Ce>ce){let qe=new Error(`Total store size (${Ce} bytes) exceeds limit (${ce} bytes)`);M?M(qe,{operation:"set"}):k||console.warn(`[gState] ${qe.message}`)}}ge=ge-O+ke,r.set(o,ke),e.set(o,le),n.set(o,(n.get(o)||0)+1),fe=null;let We=g.persist??gt;return We&&(m.set(o,{value:le,options:{...g,persist:We,encoded:g.encoded||t?.encoded}}),we&&clearTimeout(we),we=setTimeout(Fe,Se)),me("onSet",{key:o,value:le,store:Z,version:n.get(o)}),he("set",o,!0),ve(o),!0}return!1},get:o=>{if(!Ae(u,o,"read",be))return he("get",o,!1,"RBAC Denied"),null;let c=e.get(o);return me("onGet",{store:Z,key:o,value:c}),he("get",o,!0),c},compute:(o,c)=>{try{return f.has(o)||(f.set(o,{selector:c,lastValue:null,deps:new Set}),Be(o)),f.get(o).lastValue}catch(g){let v=g instanceof Error?g:new Error(String(g));return M?M(v,{operation:"compute",key:o}):k||console.error(`[gState] Compute error for "${o}": `,g),null}},watch:(o,c)=>{l.has(o)||l.set(o,new Set);let g=l.get(o);return g.add(c),()=>{g.delete(c),g.size===0&&l.delete(o)}},remove:o=>{if(!Ae(u,o,"delete",be))return he("delete",o,!1,"RBAC Denied"),!1;let c=e.get(o),g=e.delete(o);return g&&(ge-=r.get(o)||0,r.delete(o),me("onRemove",{store:Z,key:o,value:c}),fe=null),n.set(o,(n.get(o)||0)+1),I&&I.removeItem(`${ft()}${o}`),he("delete",o,!0),ve(o),g},delete:o=>Z.remove(o),deleteAll:()=>{if(Array.from(e.keys()).forEach(o=>Z.remove(o)),I){let o=h+"_";for(let c=0;c<(I.length||0);c++){let g=I.key(c);g?.startsWith(o)&&(I.removeItem(g),c--)}}return ge=0,r.clear(),fe=null,!0},list:()=>Object.fromEntries(e.entries()),use:o=>{a.add(o)},transaction:o=>{Oe=!0,me("onTransaction",{store:Z,key:"START"});try{o()}finally{Oe=!1,me("onTransaction",{store:Z,key:"END"}),De&&(De=!1,ve())}},destroy:()=>{we&&(clearTimeout(we),we=null),m.clear(),typeof window<"u"&&window.removeEventListener("beforeunload",Je),me("onDestroy",{store:Z}),s.clear(),i.clear(),l.clear(),f.clear(),p.clear(),b.clear(),e.clear(),r.clear(),ge=0,u.clear(),S.clear(),n.clear(),w.clear(),a.clear()},_addPlugin:o=>{at(Ke(),o,Z)},_removePlugin:o=>{b.delete(o)},_subscribe:(o,c)=>{if(c){i.has(c)||i.set(c,new Set);let g=i.get(c);return g.add(o),()=>{g.delete(o),g.size===0&&i.delete(c)}}return s.add(o),()=>s.delete(o)},_getVersion:o=>n.get(o)??0,addAccessRule:(o,c)=>$e(u,o,c),hasPermission:(o,c,g)=>{if(u.size===0)return!0;for(let[v,x]of u){let y;if(typeof v=="function")y=v(o,g);else try{let O=w.get(v);O||(O=new RegExp(v),w.set(v,O)),y=O.test(o)}catch{continue}if(y)return x.includes(c)||x.includes("admin")}return!1},recordConsent:(o,c,g)=>ze(S,o,c,g),hasConsent:(o,c)=>Xe(S,o,c),getConsents:o=>Ye(S,o),revokeConsent:(o,c)=>Ze(S,o,c),exportUserData:o=>et(S,o),deleteUserData:o=>tt(S,o),getSnapshot:()=>(fe||(fe=Object.fromEntries(e.entries())),fe),get plugins(){return Pe},get isReady(){return Me},get namespace(){return h},get userId(){return be},whenReady:()=>pt};["addAccessRule","recordConsent","hasConsent","getConsents","revokeConsent","exportUserData","deleteUserData"].forEach(o=>{let c=Z[o];c&&Z._registerMethod("security",o,c)});let Je=()=>{m.size>0&&Fe()};typeof window<"u"&&window.addEventListener("beforeunload",Je),I?ot(Ue(),o=>(_>0||ce>0)&&!1?je(o):0,()=>{Me=!0,fe=null,Ve(),ve()}).then(()=>{}):(Me=!0,Ve());let Te=null;return t?.sync&&(Te=new E(Z,t.sync),Z._registerMethod("sync","flush",()=>Te?.flush()),Z._registerMethod("sync","getState",()=>Te?.getState()),Z._registerMethod("sync","onStateChange",o=>Te?.onStateChange(o))),Z};import{useSyncExternalStore as ct,useDebugValue as bt,useMemo as Le,useCallback as Ee,useEffect as ut,useState as lt}from"react";var de=null,L=t=>{de&&!t?.namespace&&(t?.silent||console.warn("[gState] Store already exists. Pass a unique namespace to create additional stores."));let e=T(t);return de=e,e},U=()=>{de&&(de.destroy(),de=null)},K=t=>{let e=t||de,n=Le(()=>r=>e?e._subscribe(r):()=>{},[e]);return ct(n,()=>e?e.isReady:!1,()=>!0)},C=()=>de;function d(t,e){let n=Le(()=>e||de,[e]),r=Le(()=>{let u=()=>{},S=()=>!1,h=()=>null;return{set:S,get:h,remove:S,delete:S,deleteAll:S,list:()=>({}),compute:h,watch:()=>()=>{},use:u,transaction:u,destroy:u,_subscribe:()=>()=>{},_setSilently:u,_registerMethod:u,_addPlugin:u,_removePlugin:u,_getVersion:()=>0,get isReady(){return!1},whenReady:()=>Promise.resolve(),get plugins(){return{}},getSnapshot:()=>({}),get namespace(){return"ghost"},get userId(){}}},[]),s=n||r,i=typeof t=="function",a=i?null:t,l=i?t:null,f=Ee(u=>i?s._subscribe(u):s._subscribe(u,a),[s,i,a]),p=Ee(()=>i?l(s.getSnapshot()):s.get(a)??void 0,[s,i,a,l]),b=Ee(()=>{if(i)try{return l({})}catch{return}else return},[l,i]),m=ct(f,p,b),w=Ee((u,S)=>i?!1:s.set(a,u,S),[s,i,a]);return bt(m,u=>i?`Selector: ${JSON.stringify(u)}`:`${a}: ${JSON.stringify(u)}`),i?m:[m,w]}var pe=new Map,B=(t,e)=>{let n=t.namespace;if(pe.has(n))return console.warn(`[gState] Sync engine already exists for namespace "${n}". Call destroySync first.`),pe.get(n);let r=new E(t,e);return pe.set(n,r),r},F=t=>{let e=pe.get(t);e&&(e.destroy(),pe.delete(t))};function J(t,e){let n=e||de,r=n?.namespace||"default",s=pe.get(r),i=d(t,n),a=i[0],l=i[1],[f,p]=lt(()=>s?.getState()||{isOnline:!0,isSyncing:!1,lastSyncTimestamp:null,pendingChanges:0,conflicts:0});ut(()=>s?s.onStateChange(p):void 0,[s]);let b=Ee((m,w)=>{let u=l(m,w);if(u&&s){let S=n?.get(t);s.queueChange(t,S)}return u},[l,s,t,n]);return[a,b,f]}var W=()=>{let[t,e]=lt({isOnline:!0,isSyncing:!1,lastSyncTimestamp:null,pendingChanges:0,conflicts:0});return ut(()=>{let n=()=>{let s=!0,i=!1,a=0,l=0;pe.forEach(f=>{let p=f.getState();s=s&&p.isOnline,i=i||p.isSyncing,a+=p.pendingChanges,l+=p.conflicts}),e({isOnline:s,isSyncing:i,lastSyncTimestamp:null,pendingChanges:a,conflicts:l})};n();let r=Array.from(pe.values()).map(s=>s.onStateChange(n));return()=>r.forEach(s=>s())},[]),t},q=async t=>{let e=t||de?.namespace;if(!e)return;let n=pe.get(e);n&&await n.flush()};var Q=(t,e)=>{let n=e?.key||"async_data",r=e?.store||T({namespace:`async_${n}`,silent:!0});return r.get(n)==null&&r.set(n,{data:null,loading:!1,error:null,updatedAt:null}),Object.assign(r,{execute:async()=>{let i=r.get(n);r.set(n,{...i||{data:null,loading:!1,error:null,updatedAt:null},loading:!0,error:null}),"whenReady"in r&&!r.isReady&&await r.whenReady();try{let a=await t(),l=r.get(n);r.set(n,{...l||{data:null,loading:!1,error:null,updatedAt:null},data:a,loading:!1,updatedAt:Date.now()},{persist:e?.persist})}catch(a){let l=r.get(n);r.set(n,{...l||{data:null,loading:!1,error:null,updatedAt:null},error:a instanceof Error?a:new Error(String(a)),loading:!1})}}})};var vt=()=>({name:"gstate-immer",hooks:{onInstall:({store:t})=>{t._registerMethod("immer","setWithProduce",((e,n)=>t.set(e,n)))}}});var kt=t=>{let e=[],n=-1,r=!1,s=t?.limit||50;return{name:"gstate-undo-redo",hooks:{onInstall:({store:i})=>{e.push(i.list()),n=0,i._registerMethod("undoRedo","undo",()=>{if(n>0){r=!0,n--;let a=e[n];return a?(Object.entries(a).forEach(([l,f])=>{i._setSilently(l,f)}),r=!1,!0):!1}return!1}),i._registerMethod("undoRedo","redo",()=>{if(n<e.length-1){r=!0,n++;let a=e[n];return a?(Object.entries(a).forEach(([l,f])=>{i._setSilently(l,f)}),r=!1,!0):!1}return!1}),i._registerMethod("undoRedo","canUndo",()=>n>0),i._registerMethod("undoRedo","canRedo",()=>n<e.length-1)},onSet:({store:i})=>{r||(n<e.length-1&&(e=e.slice(0,n+1)),e.push(i.list()),e.length>s?e.shift():n++)}}}};var Ct=t=>({name:"gstate-schema",hooks:{onSet:({key:e,value:n})=>{if(!e)return;let r=t[e];if(r){let s=r(n);if(s!==!0)throw new Error(`[Schema Error] Validation failed for key "${e}": ${s===!1?"Invalid type":s}`)}}}});var xt=t=>{let r=globalThis.__REDUX_DEVTOOLS_EXTENSION__;if(!r?.connect)return{name:"gstate-devtools-noop",hooks:{}};let s=null;return{name:"gstate-devtools",hooks:{onInstall:({store:i})=>{s=r.connect({name:t?.name||"Magnetar Store"}),s.init(i.list())},onSet:({key:i,store:a})=>{!i||!s||s.send(`SET_${i.toUpperCase()}`,a.list())},onRemove:({key:i,store:a})=>{!i||!s||s.send(`REMOVE_${i.toUpperCase()}`,a.list())}}}};var Et=()=>{let t=new Map;return{name:"gstate-snapshot",hooks:{onInstall:({store:e})=>{e._registerMethod("snapshot","takeSnapshot",(n=>{t.set(n,e.list())})),e._registerMethod("snapshot","restoreSnapshot",(n=>{let r=t.get(n);return r?(e.transaction(()=>{Object.entries(r).forEach(([s,i])=>{e.set(s,i)})}),!0):!1})),e._registerMethod("snapshot","listSnapshots",(()=>Array.from(t.keys()))),e._registerMethod("snapshot","deleteSnapshot",(n=>t.delete(n))),e._registerMethod("snapshot","clearSnapshots",(()=>t.clear()))}}}};var _t=t=>({name:"gstate-guard",hooks:{onBeforeSet:({key:e,value:n,store:r})=>{if(!e)return;let s=t[e];if(s){let i=s(n)}}}});var Rt=t=>({name:"gstate-analytics",hooks:{onSet:({key:e,value:n})=>{e&&(!t.keys||t.keys.includes(e))&&t.provider({key:e,value:n,action:"SET"})},onRemove:({key:e})=>{e&&(!t.keys||t.keys.includes(e))&&t.provider({key:e,value:null,action:"REMOVE"})}}});var Pt=t=>{let e=new BroadcastChannel(t?.channelName||"gstate_sync"),n=!1;return{name:"gstate-sync",hooks:{onInstall:({store:r})=>{e.onmessage=s=>{let{key:i,value:a,action:l}=s.data;i&&(n=!0,l==="REMOVE"?r.remove(i):r.set(i,a),n=!1)}},onSet:({key:r,value:s})=>{!r||n||e.postMessage({key:r,value:s,action:"SET"})},onRemove:({key:r})=>{!r||n||e.postMessage({key:r,action:"REMOVE"})},onDestroy:()=>{e.close()}}}};var Tt=()=>({name:"gstate-debug-noop",hooks:{}});var It=(t={})=>{let e=t.dbName||"rgs-db",n=t.storeName||"states",r=t.version||1,s=null,i=()=>new Promise((p,b)=>{if(s)return p(s);let m=indexedDB.open(e,r);m.onerror=()=>b(m.error),m.onsuccess=()=>{s=m.result,p(s)},m.onupgradeneeded=w=>{let u=w.target.result;u.objectStoreNames.contains(n)||u.createObjectStore(n)}}),a=async(p,b)=>{let m=await i();return new Promise((w,u)=>{let k=m.transaction(n,"readwrite").objectStore(n).put(b,p);k.onsuccess=()=>w(),k.onerror=()=>u(k.error)})},l=async p=>{let b=await i();return new Promise((m,w)=>{let h=b.transaction(n,"readonly").objectStore(n).get(p);h.onsuccess=()=>m(h.result),h.onerror=()=>w(h.error)})},f=async p=>{let b=await i();return new Promise((m,w)=>{let h=b.transaction(n,"readwrite").objectStore(n).delete(p);h.onsuccess=()=>m(),h.onerror=()=>w(h.error)})};return{name:"indexedDB",hooks:{onInstall:({store:p})=>{p._registerMethod("indexedDB","clear",async()=>{(await i()).transaction(n,"readwrite").objectStore(n).clear()})},onInit:async({store:p})=>{let u=(await i()).transaction(n,"readonly").objectStore(n).getAllKeys();u.onsuccess=async()=>{let S=u.result,h=p.namespace+"_";for(let k of S)if(k.startsWith(h)){let Se=await l(k);if(Se){let ae=k.substring(h.length);p._setSilently(ae,Se.d)}}}},onSet:async({key:p,value:b,store:m})=>{if(!p)return;let w=m.namespace+"_",u={d:b,t:Date.now(),v:m._getVersion?.(p)||1};await a(`${w}${p}`,u)},onRemove:async({key:p,store:b})=>{if(!p)return;let m=b.namespace+"_";await f(`${m}${p}`)}}}};var At=t=>{let{adapter:e,autoSyncInterval:n}=t,r=new Map,s={lastSyncTimestamp:null,totalKeysSynced:0,totalBytesSynced:0,syncCount:0,lastDuration:0,errors:0},i=null;return{name:"cloudSync",hooks:{onInstall:({store:a})=>{a._registerMethod("cloudSync","sync",async()=>{let l=performance.now(),f={},p=0;try{let b=a.list(),m=Object.keys(b);for(let u of m){let S=a._getVersion?.(u)||0,h=r.get(u)||0;if(S>h){let k=b[u];f[u]=k,p+=JSON.stringify(k).length,r.set(u,S)}}if(Object.keys(f).length===0)return{status:"no-change",stats:s};if(await e.save(f))return s.lastSyncTimestamp=Date.now(),s.totalKeysSynced+=Object.keys(f).length,s.totalBytesSynced+=p,s.syncCount++,s.lastDuration=performance.now()-l,t.onSync&&t.onSync(s),{status:"success",stats:s};throw new Error(`Adapter ${e.name} failed to save.`)}catch(b){return s.errors++,console.error(`[gState] Cloud Sync Failed (${e.name}):`,b),{status:"error",error:String(b),stats:s}}}),a._registerMethod("cloudSync","getStats",()=>s),n&&n>0&&(i=setInterval(()=>{let f=a.plugins.cloudSync;f&&f.sync()},n))},onDestroy:()=>{i&&clearInterval(i)}}}},Ot=(t,e)=>({name:"MongoDB-Atlas",save:async n=>(await fetch(`${t}/action/updateOne`,{method:"POST",headers:{"Content-Type":"application/json","api-key":e},body:JSON.stringify({dataSource:"Cluster0",database:"rgs_cloud",collection:"user_states",filter:{id:"global_state"},update:{$set:{data:n,updatedAt:Date.now()}},upsert:!0})})).ok}),Dt=(t,e)=>({name:"Firebase-Firestore",save:async n=>{try{return((...i)=>{})("[Mock] Firestore Syncing:",n),!0}catch{return!1}}}),Mt=(t,e)=>({name:"SQL-REST-API",save:async n=>(await fetch(t,{method:"PATCH",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)})).ok});var On=t=>({name:"gstate-logger",hooks:{onSet:({key:e,value:n,version:r})=>{let s=new Date().toLocaleTimeString(),i=`[gState] SET: ${e} (v${r}) @ ${s}`;t?.collapsed?console.groupCollapsed(i):console.group(i),console.info("%c Value:","color: #4CAF50; font-weight: bold;",n),console.groupEnd()},onRemove:({key:e})=>{console.warn(`[gState] REMOVED: ${e}`)},onTransaction:({key:e})=>{e==="START"?console.group("\u2500\u2500 TRANSACTION START \u2500\u2500"):console.groupEnd()}}});var H=(t,e)=>{let r=T(typeof e=="string"?{namespace:e}:e);t&&Object.entries(t).forEach(([i,a])=>{r.get(i)===null&&r._setSilently(i,a)});let s=i=>d(i,r);return typeof window<"u"&&(window.gState=r,window.rgs=r),Object.assign(s,r)};var Y=(t,e)=>C()?.addAccessRule(t,e),ee=(t,e,n)=>C()?.hasPermission(t,e,n)??!0,te=(t,e,n)=>{let r=C();if(!r)throw new Error("[gState] recordConsent failed: No store found. call initState() first.");return r.recordConsent(t,e,n)},ne=(t,e)=>C()?.hasConsent(t,e)??!1,re=t=>C()?.getConsents(t)??[],se=(t,e)=>C()?.revokeConsent(t,e),oe=t=>{let e=C();if(!e)throw new Error("[gState] exportUserData failed: No store found.");return e.exportUserData(t)},ie=t=>{let e=C();if(!e)throw new Error("[gState] deleteUserData failed: No store found.");return e.deleteUserData(t)},G=()=>{},X=()=>{};export{E as SyncEngine,Y as addAccessRule,Rt as analyticsPlugin,G as clearAccessRules,X as clearAllConsents,At as cloudSyncPlugin,Q as createAsyncStore,Dt as createFirestoreAdapter,Ot as createMongoAdapter,Mt as createSqlRestAdapter,T as createStore,N as createSyncEngine,Tt as debugPlugin,ie as deleteUserData,U as destroyState,F as destroySync,xt as devToolsPlugin,j as exportKey,oe as exportUserData,V as generateEncryptionKey,re as getConsents,C as getStore,H as gstate,_t as guardPlugin,ne as hasConsent,ee as hasPermission,vt as immerPlugin,$ as importKey,It as indexedDBPlugin,L as initState,B as initSync,D as isCryptoAvailable,P as logAudit,On as loggerPlugin,te as recordConsent,se as revokeConsent,R as sanitizeValue,Ct as schemaPlugin,z as setAuditLogger,Et as snapshotPlugin,Pt as syncPlugin,q as triggerSync,kt as undoRedoPlugin,d as useGState,K as useIsStoreReady,d as useSimpleState,d as useStore,W as useSyncStatus,J as useSyncedState,A as validateKey};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../core/store.ts", "../core/security.ts", "../core/utils.ts", "../core/persistence.ts", "../core/plugins.ts", "../core/sync.ts", "../core/hooks.ts", "../core/async.ts", "../plugins/official/immer.plugin.ts", "../plugins/official/undo-redo.plugin.ts", "../plugins/official/schema.plugin.ts", "../plugins/official/devtools.plugin.ts", "../plugins/official/snapshot.plugin.ts", "../plugins/official/guard.plugin.ts", "../plugins/official/analytics.plugin.ts", "../plugins/official/sync.plugin.ts", "../plugins/official/debug.plugin.ts", "../plugins/official/indexeddb.plugin.ts", "../plugins/official/cloud-sync.plugin.ts", "../plugins/index.ts", "../index.ts"],
|
|
4
|
+
"sourcesContent": ["import { produce as _immerProduce, freeze as _immerFreeze } from 'immer'\r\n\r\nimport * as Security from \"./security\"\r\nimport * as Persistence from \"./persistence\"\r\nimport * as Plugins from \"./plugins\"\r\nimport { deepClone, isEqual } from './utils'\r\nimport { SyncEngine } from './sync'\r\n\r\nimport type {\r\n IStore, StoreConfig, PersistOptions, StoreSubscriber,\r\n ComputedSelector, WatcherCallback, IPlugin, PluginHookName,\r\n PluginContext, Middleware, CustomStorage, GStatePlugins\r\n} from './types'\r\n\r\n/**\r\n * Enterprise Storage Adapters\r\n */\r\nexport const StorageAdapters = {\r\n local: (): CustomStorage | null => (typeof window !== \"undefined\" ? window.localStorage : null),\r\n session: (): CustomStorage | null => (typeof window !== \"undefined\" ? window.sessionStorage : null),\r\n memory: (): CustomStorage => {\r\n const _m = new Map<string, string>()\r\n return {\r\n getItem: (k: string) => _m.get(k) || null,\r\n setItem: (k: string, v: string) => _m.set(k, v),\r\n removeItem: (k: string) => _m.delete(k),\r\n key: (i: number) => Array.from(_m.keys())[i] || null,\r\n get length() { return _m.size }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Creates an enterprise-grade state management store.\r\n */\r\nexport const createStore = <S extends Record<string, unknown> = Record<string, unknown>>(config?: StoreConfig<S>): IStore<S> => {\r\n const\r\n _store = new Map<string, unknown>(),\r\n _versions = new Map<string, number>(),\r\n _sizes = new Map<string, number>(), // Internal cache for key sizes\r\n _listeners = new Set<StoreSubscriber>(),\r\n _keyListeners = new Map<string, Set<StoreSubscriber>>(),\r\n _middlewares = new Set<Middleware>(),\r\n _watchers = new Map<string, Set<WatcherCallback<unknown>>>(),\r\n _computed = new Map<string, { selector: ComputedSelector<unknown>, lastValue: unknown, deps: Set<string> }>(),\r\n _computedDeps = new Map<string, Set<string>>(),\r\n _plugins = new Map<string, IPlugin<S>>(),\r\n _diskQueue = new Map<string, { value: unknown, options: PersistOptions }>(),\r\n _regexCache = new Map<string, RegExp>(), // Performance: Cache for RBAC regexes\r\n\r\n // Multi-store isolation for Security\r\n _accessRules: Security.AccessRulesMap = new Map(),\r\n _consents: Security.ConsentsMap = new Map(),\r\n\r\n _namespace = config?.namespace || \"gstate\",\r\n _silent = config?.silent ?? false,\r\n _debounceTime = config?.debounceTime ?? 150,\r\n _currentVersion = config?.version ?? 0,\r\n _storage = config?.storage || StorageAdapters.local(),\r\n _onError = config?.onError,\r\n _maxObjectSize = config?.maxObjectSize ?? 0,\r\n _maxTotalSize = config?.maxTotalSize ?? 0,\r\n _encryptionKey = config?.encryptionKey ?? null,\r\n _validateInput = config?.validateInput ?? true,\r\n _auditEnabled = config?.auditEnabled ?? true,\r\n _userId = config?.userId,\r\n _immer = config?.immer ?? true,\r\n _persistByDefault = config?.persistByDefault ?? config?.persistence ?? config?.persist ?? false\r\n\r\n if (config?.accessRules) {\r\n config.accessRules.forEach(rule => Security.addAccessRule(_accessRules, rule.pattern, rule.permissions))\r\n }\r\n\r\n let\r\n _isTransaction = false, _pendingEmit = false, _isReady = false, _totalSize = 0,\r\n _diskTimer: ReturnType<typeof setTimeout> | null = null,\r\n _snapshot: S | null = null // Cache for stable state snapshot\r\n\r\n let _readyResolver: () => void\r\n const _readyPromise = new Promise<void>(resolve => { _readyResolver = resolve })\r\n\r\n // --- Context Helpers ---\r\n\r\n const _getPrefix = () => `${_namespace}_`\r\n\r\n const getPersistenceContext = (): Persistence.PersistenceContext => ({\r\n store: _store, versions: _versions, sizes: _sizes, totalSize: _totalSize,\r\n storage: _storage, config: config || {}, diskQueue: _diskQueue,\r\n encryptionKey: _encryptionKey, audit: _audit,\r\n onError: _onError as unknown as ((error: Error, metadata?: Record<string, unknown>) => void) | undefined,\r\n silent: _silent, debounceTime: _debounceTime, currentVersion: _currentVersion\r\n })\r\n\r\n const getPluginContext = (): Plugins.PluginManagerContext<S> => ({\r\n plugins: _plugins,\r\n onError: _onError as unknown as ((error: Error, metadata?: Record<string, unknown>) => void) | undefined,\r\n silent: _silent\r\n })\r\n\r\n /**\r\n * Enterprise-grade iterative walker for precise memory estimation.\r\n * Faster than JSON.stringify and handles circular references accurately.\r\n */\r\n const _calculateSize = (val: unknown): number => {\r\n if (val === null || val === undefined) return 0\r\n const type = typeof val\r\n if (type === 'boolean') return 4\r\n if (type === 'number') return 8\r\n if (type === 'string') return (val as string).length * 2\r\n if (type !== 'object') return 0\r\n\r\n let bytes = 0\r\n const stack: unknown[] = [val]\r\n const seen = new WeakSet<object>()\r\n\r\n while (stack.length > 0) {\r\n const value = stack.pop()\r\n if (typeof value === 'boolean') { bytes += 4 }\r\n else if (typeof value === 'number') { bytes += 8 }\r\n else if (typeof value === 'string') { bytes += value.length * 2 }\r\n else if (typeof value === 'object' && value !== null) {\r\n const obj = value as Record<string, unknown>\r\n if (seen.has(obj)) continue\r\n seen.add(obj)\r\n if (Array.isArray(obj)) {\r\n for (let i = 0; i < obj.length; i++) stack.push(obj[i])\r\n } else {\r\n for (const key of Object.keys(obj)) {\r\n bytes += key.length * 2\r\n stack.push(obj[key])\r\n }\r\n }\r\n }\r\n }\r\n return bytes\r\n }\r\n\r\n const _runHook = (name: PluginHookName, context: PluginContext<S>) => {\r\n Plugins.runHook(getPluginContext(), name, context)\r\n }\r\n\r\n const _audit = (action: 'set' | 'get' | 'delete' | 'hydrate', key: string, success: boolean, error?: string) => {\r\n if (_auditEnabled && Security.isAuditActive() && Security.logAudit) {\r\n Security.logAudit({ timestamp: Date.now(), action, key, userId: _userId, success, error })\r\n }\r\n }\r\n\r\n // --- Reactivity ---\r\n\r\n const _updateComputed = (key: string) => {\r\n const comp = _computed.get(key)\r\n if (!comp) return\r\n\r\n const depsFound = new Set<string>()\r\n const getter = <V>(k: string): V | null => {\r\n depsFound.add(k)\r\n if (_computed.has(k)) return _computed.get(k)!.lastValue as V\r\n return instance.get(k) as V | null\r\n }\r\n\r\n const newValue = comp.selector(getter)\r\n\r\n // Update dependencies\r\n comp.deps.forEach(d => {\r\n if (!depsFound.has(d)) {\r\n const dependents = _computedDeps.get(d)\r\n if (dependents) { dependents.delete(key); if (dependents.size === 0) _computedDeps.delete(d) }\r\n }\r\n })\r\n depsFound.forEach(d => {\r\n if (!comp.deps.has(d)) {\r\n if (!_computedDeps.has(d)) _computedDeps.set(d, new Set())\r\n _computedDeps.get(d)!.add(key)\r\n }\r\n })\r\n comp.deps = depsFound\r\n\r\n if (!isEqual(comp.lastValue, newValue)) {\r\n comp.lastValue = (_immer && newValue !== null && typeof newValue === 'object') ? _immerFreeze(deepClone(newValue), true) : newValue\r\n _versions.set(key, (_versions.get(key) || 0) + 1)\r\n _emit(key)\r\n }\r\n }\r\n\r\n const _emit = (changedKey?: string) => {\r\n if (changedKey) {\r\n // 1. Update computed dependent on this key\r\n if (_computedDeps.has(changedKey)) {\r\n const dependents = _computedDeps.get(changedKey)!\r\n for (const dependentKey of dependents) {\r\n _updateComputed(dependentKey)\r\n }\r\n }\r\n\r\n // 2. Notify Watchers\r\n const watchers = _watchers.get(changedKey)\r\n if (watchers) {\r\n const val = instance.get(changedKey)\r\n for (const w of watchers) {\r\n try { w(val) }\r\n catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (_onError) _onError(error, { operation: 'watcher', key: changedKey })\r\n else if (!_silent) console.error(`[gState] Watcher error for \"${changedKey}\":`, e)\r\n }\r\n }\r\n }\r\n\r\n // 3. Notify Key Listeners\r\n const keyListeners = _keyListeners.get(changedKey)\r\n if (keyListeners) {\r\n for (const l of keyListeners) {\r\n try { l() }\r\n catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (_onError) _onError(error, { operation: 'keyListener', key: changedKey })\r\n else if (!_silent) console.error(`[gState] Listener error for \"${changedKey}\":`, e)\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (_isTransaction) { _pendingEmit = true; return }\r\n\r\n // 4. Notify Global Listeners\r\n for (const l of _listeners) {\r\n try { l() }\r\n catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (_onError) _onError(error, { operation: 'listener' })\r\n else if (!_silent) console.error(`[gState] Global listener error: `, e)\r\n }\r\n }\r\n }\r\n\r\n const _flushDisk = async () => {\r\n // We pass current values to the persistence module\r\n // Note: totalSize update is not handled here as flush doesn't change memory size\r\n Persistence.flushDisk(getPersistenceContext())\r\n }\r\n\r\n /**\r\n * Plugin namespace for safely storing plugin methods.\r\n */\r\n const _methodNamespace: Record<string, Record<string, unknown>> = {}\r\n\r\n const instance: IStore<S> = {\r\n _setSilently: (key: string, value: unknown) => {\r\n const oldSize = _sizes.get(key) || 0, frozen = (_immer && value !== null && typeof value === 'object') ? _immerFreeze!(deepClone(value), true) : value\r\n const hasLimits = (_maxObjectSize > 0 || _maxTotalSize > 0) && process.env.NODE_ENV !== 'production'\r\n const newSize = hasLimits ? _calculateSize(frozen) : 0\r\n\r\n _totalSize = _totalSize - oldSize + newSize\r\n _sizes.set(key, newSize)\r\n _store.set(key, frozen); _versions.set(key, (_versions.get(key) || 0) + 1)\r\n _snapshot = null // Invalidate snapshot\r\n },\r\n /**\r\n * Registers a custom method on the store instance.\r\n * @param pluginName - Plugin name\r\n * @param methodName - Method name\r\n * @param fn - Method function\r\n */\r\n _registerMethod: (pluginName: string, methodName: string, fn: (...args: unknown[]) => unknown) => {\r\n const isUnsafeKey = (key: string): boolean =>\r\n key === '__proto__' || key === 'constructor' || key === 'prototype'\r\n\r\n if (isUnsafeKey(pluginName) || isUnsafeKey(methodName)) {\r\n console.warn('[gState] Refusing to register method with unsafe key:', pluginName, methodName)\r\n return\r\n }\r\n\r\n if (!_methodNamespace[pluginName]) _methodNamespace[pluginName] = {}\r\n _methodNamespace[pluginName]![methodName] = fn\r\n },\r\n set: (key: string, valOrUp: unknown, options: PersistOptions = {}): boolean => {\r\n const oldVal = _store.get(key), newVal = _immer && typeof valOrUp === 'function' ? _immerProduce!(oldVal, valOrUp as (draft: unknown) => void) : valOrUp\r\n if (_validateInput && !Security.validateKey(key)) { if (!_silent) console.warn(`[gState] Invalid key: ${key}`); return false }\r\n if (!Security.hasPermission(_accessRules, key, 'write', _userId)) { _audit('set', key, false, 'RBAC Denied'); if (!_silent) console.error(`[gState] RBAC Denied for \"${key}\"`); return false }\r\n\r\n const sani = _validateInput ? Security.sanitizeValue(newVal) : newVal\r\n const oldSize = _sizes.get(key) || 0\r\n _runHook('onBeforeSet', { key, value: sani, store: instance, version: _versions.get(key) || 0 })\r\n\r\n const frozen = (_immer && sani !== null && typeof sani === 'object') ? _immerFreeze(deepClone(sani), true) : sani\r\n\r\n if (!isEqual(oldVal, frozen)) {\r\n const hasLimits = (_maxObjectSize > 0 || _maxTotalSize > 0) && process.env.NODE_ENV !== 'production'\r\n const finalSize = hasLimits ? _calculateSize(frozen) : 0\r\n\r\n if (_maxObjectSize > 0 && finalSize > _maxObjectSize) {\r\n const error = new Error(`Object size (${finalSize} bytes) exceeds maxObjectSize (${_maxObjectSize} bytes)`)\r\n if (_onError) _onError(error, { operation: 'set', key })\r\n else if (!_silent) console.warn(`[gState] ${error.message} for \"${key}\"`)\r\n }\r\n\r\n if (_maxTotalSize > 0) {\r\n const est = _totalSize - oldSize + finalSize\r\n if (est > _maxTotalSize) {\r\n const error = new Error(`Total store size (${est} bytes) exceeds limit (${_maxTotalSize} bytes)`)\r\n if (_onError) _onError(error, { operation: 'set' })\r\n else if (!_silent) console.warn(`[gState] ${error.message}`)\r\n }\r\n }\r\n\r\n _totalSize = _totalSize - oldSize + finalSize\r\n _sizes.set(key, finalSize)\r\n _store.set(key, frozen); _versions.set(key, (_versions.get(key) || 0) + 1)\r\n\r\n _snapshot = null // Invalidate snapshot\r\n\r\n const shouldPersist = options.persist ?? _persistByDefault\r\n if (shouldPersist) {\r\n _diskQueue.set(key, { value: frozen, options: { ...options, persist: shouldPersist, encoded: options.encoded || config?.encoded } }); if (_diskTimer) clearTimeout(_diskTimer); _diskTimer = setTimeout(_flushDisk, _debounceTime)\r\n }\r\n _runHook('onSet', { key, value: frozen, store: instance, version: _versions.get(key) })\r\n _audit('set', key, true)\r\n _emit(key)\r\n return true\r\n }\r\n return false\r\n },\r\n get: <T>(key: string): T | null => {\r\n if (!Security.hasPermission(_accessRules, key, 'read', _userId)) {\r\n _audit('get', key, false, 'RBAC Denied')\r\n return null\r\n }\r\n const val = _store.get(key)\r\n _runHook('onGet', { store: instance, key, value: val })\r\n _audit('get', key, true)\r\n return val as T\r\n },\r\n compute: <T>(key: string, selector: ComputedSelector<T>): T => {\r\n try {\r\n if (!_computed.has(key)) { _computed.set(key, { selector: selector as ComputedSelector<unknown>, lastValue: null, deps: new Set() }); _updateComputed(key) }\r\n return _computed.get(key)!.lastValue as T\r\n } catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (_onError) _onError(error, { operation: 'compute', key })\r\n else if (!_silent) console.error(`[gState] Compute error for \"${key}\": `, e)\r\n return null as unknown as T\r\n }\r\n },\r\n watch: <T>(key: string, callback: WatcherCallback<T>) => {\r\n if (!_watchers.has(key)) _watchers.set(key, new Set())\r\n const set = _watchers.get(key)!; set.add(callback as WatcherCallback<unknown>)\r\n return () => { set.delete(callback as WatcherCallback<unknown>); if (set.size === 0) _watchers.delete(key) }\r\n },\r\n remove: (key: string): boolean => {\r\n if (!Security.hasPermission(_accessRules, key, 'delete', _userId)) {\r\n _audit('delete', key, false, 'RBAC Denied')\r\n return false\r\n }\r\n const old = _store.get(key), deleted = _store.delete(key)\r\n if (deleted) {\r\n _totalSize -= (_sizes.get(key) || 0)\r\n _sizes.delete(key)\r\n _runHook('onRemove', { store: instance, key, value: old })\r\n _snapshot = null // Invalidate snapshot\r\n }\r\n _versions.set(key, (_versions.get(key) || 0) + 1)\r\n if (_storage) _storage.removeItem(`${_getPrefix()}${key}`)\r\n\r\n _audit('delete', key, true)\r\n _emit(key); return deleted\r\n },\r\n delete: (key: string) => instance.remove(key),\r\n deleteAll: () => {\r\n Array.from(_store.keys()).forEach(k => instance.remove(k))\r\n if (_storage) {\r\n const prefix = _namespace + \"_\"\r\n for (let i = 0; i < (_storage.length || 0); i++) {\r\n const k = _storage.key(i); if (k?.startsWith(prefix)) { _storage.removeItem(k); i-- }\r\n }\r\n }\r\n _totalSize = 0\r\n _sizes.clear()\r\n _snapshot = null // Invalidate snapshot\r\n return true\r\n },\r\n list: () => Object.fromEntries(_store.entries()),\r\n use: (m: Middleware) => { _middlewares.add(m) },\r\n transaction: (fn: () => void) => {\r\n _isTransaction = true; _runHook('onTransaction', { store: instance, key: 'START' })\r\n try { fn() } finally { _isTransaction = false; _runHook('onTransaction', { store: instance, key: 'END' }); if (_pendingEmit) { _pendingEmit = false; _emit() } }\r\n },\r\n destroy: () => {\r\n if (_diskTimer) { clearTimeout(_diskTimer); _diskTimer = null }\r\n _diskQueue.clear()\r\n if (typeof window !== 'undefined') window.removeEventListener('beforeunload', _unloadHandler)\r\n _runHook('onDestroy', { store: instance })\r\n _listeners.clear(); _keyListeners.clear(); _watchers.clear(); _computed.clear()\r\n _computedDeps.clear(); _plugins.clear(); _store.clear(); _sizes.clear(); _totalSize = 0\r\n _accessRules.clear(); _consents.clear(); _versions.clear(); _regexCache.clear(); _middlewares.clear()\r\n },\r\n _addPlugin: (p: IPlugin<S>) => {\r\n Plugins.installPlugin(getPluginContext(), p, instance)\r\n },\r\n _removePlugin: (name: string) => { _plugins.delete(name) },\r\n _subscribe: (cb: StoreSubscriber, key?: string) => {\r\n if (key) {\r\n if (!_keyListeners.has(key)) _keyListeners.set(key, new Set())\r\n const set = _keyListeners.get(key)!; set.add(cb)\r\n return () => { set.delete(cb); if (set.size === 0) _keyListeners.delete(key) }\r\n }\r\n _listeners.add(cb); return () => _listeners.delete(cb)\r\n },\r\n _getVersion: (key: string) => _versions.get(key) ?? 0,\r\n\r\n // Enterprise Security & Compliance\r\n addAccessRule: (pattern, permissions) => Security.addAccessRule(_accessRules, pattern, permissions),\r\n hasPermission: (key, action, userId) => {\r\n if (_accessRules.size === 0) return true\r\n for (const [pattern, perms] of _accessRules) {\r\n let matches: boolean\r\n if (typeof pattern === 'function') {\r\n matches = pattern(key, userId)\r\n } else {\r\n try {\r\n let re = _regexCache.get(pattern)\r\n if (!re) { re = new RegExp(pattern); _regexCache.set(pattern, re) }\r\n matches = re.test(key)\r\n } catch { continue }\r\n }\r\n if (matches) return perms.includes(action) || perms.includes('admin')\r\n }\r\n return false\r\n },\r\n recordConsent: (userId, purpose, granted) => Security.recordConsent(_consents, userId, purpose, granted),\r\n hasConsent: (userId, purpose) => Security.hasConsent(_consents, userId, purpose),\r\n getConsents: (userId) => Security.getConsents(_consents, userId),\r\n revokeConsent: (userId, purpose) => Security.revokeConsent(_consents, userId, purpose),\r\n exportUserData: (userId) => Security.exportUserData(_consents, userId),\r\n deleteUserData: (userId) => Security.deleteUserData(_consents, userId),\r\n\r\n getSnapshot: (): S => {\r\n if (!_snapshot) {\r\n _snapshot = Object.fromEntries(_store.entries()) as S\r\n }\r\n return _snapshot\r\n },\r\n\r\n get plugins() { return _methodNamespace as unknown as GStatePlugins },\r\n get isReady() { return _isReady },\r\n get namespace() { return _namespace },\r\n get userId() { return _userId },\r\n whenReady: () => _readyPromise\r\n }\r\n\r\n const secMethods = ['addAccessRule', 'recordConsent', 'hasConsent', 'getConsents', 'revokeConsent', 'exportUserData', 'deleteUserData']\r\n secMethods.forEach(m => {\r\n const fn = (instance as unknown as Record<string, (...args: unknown[]) => unknown>)[m]\r\n if (fn) instance._registerMethod('security', m, fn)\r\n })\r\n\r\n const _unloadHandler = () => { if (_diskQueue.size > 0) _flushDisk() }\r\n if (typeof window !== 'undefined') window.addEventListener('beforeunload', _unloadHandler)\r\n\r\n if (_storage) {\r\n Persistence.hydrateStore(\r\n getPersistenceContext(),\r\n // We pass the calculateSize function to update memory usage correctly after hydration\r\n (val) => {\r\n const hasLimits = (_maxObjectSize > 0 || _maxTotalSize > 0) && process.env.NODE_ENV !== 'production'\r\n return hasLimits ? _calculateSize(val) : 0\r\n },\r\n () => { _isReady = true; _snapshot = null; _readyResolver(); _emit() }\r\n ).then(() => {\r\n // Hydration logic handles isReady and emit internally via callback or promise resolution if needed\r\n // But here we rely on the callback passed to hydrateStore\r\n })\r\n } else { _isReady = true; _readyResolver!() }\r\n\r\n // Initialize sync engine if configured\r\n let _syncEngine: SyncEngine<S> | null = null\r\n if ((config as StoreConfig<S>)?.sync) {\r\n _syncEngine = new SyncEngine(instance, (config as StoreConfig<S>).sync!)\r\n // Register sync methods on the store\r\n instance._registerMethod('sync', 'flush', () => _syncEngine?.flush())\r\n instance._registerMethod('sync', 'getState', () => _syncEngine?.getState())\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n instance._registerMethod('sync', 'onStateChange', (cb: any) => _syncEngine?.onStateChange(cb))\r\n }\r\n\r\n return instance\r\n}\r\n", "/**\r\n * Enterprise Security Module - AES-256-GCM\r\n * RBAC, Audit Logging, GDPR Compliance, and Input Validation\r\n */\r\n\r\n// --- Infrastructure ---\r\n\r\n/**\r\n * Checks if Web Crypto API is available in the current environment\r\n */\r\nexport const isCryptoAvailable = typeof crypto !== 'undefined' &&\r\n typeof crypto.subtle !== 'undefined' &&\r\n typeof crypto.subtle.generateKey === 'function'\r\n\r\nexport interface EncryptionKey {\r\n key: CryptoKey\r\n iv: Uint8Array\r\n}\r\n\r\n// --- AES-256-GCM Encryption ---\r\n\r\n/**\r\n * Generates a secure AES-256-GCM key and IV\r\n * @returns Promise<EncryptionKey>\r\n */\r\nexport const generateEncryptionKey = async (): Promise<EncryptionKey> => {\r\n if (!isCryptoAvailable) throw new Error('Web Crypto API not available')\r\n\r\n const\r\n key = await crypto.subtle.generateKey(\r\n { name: 'AES-GCM', length: 256 },\r\n true,\r\n ['encrypt', 'decrypt']\r\n ),\r\n iv = crypto.getRandomValues(new Uint8Array(12))\r\n\r\n return { key, iv }\r\n}\r\n\r\n/**\r\n * Exports an encryption key to base64 strings\r\n * @param encryptionKey Key and IV to export\r\n * @returns Promise<{ key: string, iv: string }>\r\n */\r\nexport const exportKey = async (encryptionKey: EncryptionKey): Promise<{ key: string, iv: string }> => {\r\n const exportedKey = await crypto.subtle.exportKey('raw', encryptionKey.key)\r\n\r\n return {\r\n key: btoa(String.fromCharCode(...new Uint8Array(exportedKey))),\r\n iv: btoa(String.fromCharCode(...encryptionKey.iv))\r\n }\r\n}\r\n\r\n/**\r\n * Imports an encryption key from base64 strings\r\n * @param keyData Base64 encoded key\r\n * @param ivData Base64 encoded IV\r\n * @returns Promise<EncryptionKey>\r\n */\r\nexport const importKey = async (keyData: string, ivData: string): Promise<EncryptionKey> => {\r\n const\r\n keyBytes = Uint8Array.from(atob(keyData), c => c.charCodeAt(0)),\r\n ivBytes = Uint8Array.from(atob(ivData), c => c.charCodeAt(0)),\r\n key = await crypto.subtle.importKey(\r\n 'raw', keyBytes, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']\r\n )\r\n\r\n return { key, iv: ivBytes }\r\n}\r\n\r\n/**\r\n * Encrypts data using AES-256-GCM\r\n * @param data Data to encrypt\r\n * @param encryptionKey Key and IV\r\n * @returns Promise<string> Base64 combined IV + ciphertext\r\n */\r\nexport const encrypt = async (data: unknown, encryptionKey: EncryptionKey): Promise<string> => {\r\n const\r\n encoder = new TextEncoder(),\r\n encoded = encoder.encode(JSON.stringify(data)),\r\n encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: encryptionKey.iv as unknown as BufferSource },\r\n encryptionKey.key,\r\n encoded\r\n ),\r\n combined = new Uint8Array(encryptionKey.iv.length + encrypted.byteLength)\r\n\r\n combined.set(encryptionKey.iv)\r\n combined.set(new Uint8Array(encrypted), encryptionKey.iv.length)\r\n\r\n return btoa(String.fromCharCode(...combined))\r\n}\r\n\r\n/**\r\n * Decrypts AES-256-GCM encrypted data\r\n * @param encryptedData Base64 combined IV + ciphertext\r\n * @param encryptionKey Expected key\r\n * @returns Promise<T> Decrypted data\r\n */\r\nexport const decrypt = async <T>(encryptedData: string, encryptionKey: EncryptionKey): Promise<T> => {\r\n const\r\n combined = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0)),\r\n iv = combined.slice(0, 12),\r\n ciphertext = combined.slice(12),\r\n decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: iv as unknown as BufferSource },\r\n encryptionKey.key,\r\n ciphertext\r\n )\r\n\r\n return JSON.parse(new TextDecoder().decode(decrypted))\r\n}\r\n\r\n// --- AUDIT LOGGING ---\r\n\r\nexport interface AuditEntry {\r\n timestamp: number\r\n action: 'set' | 'get' | 'delete' | 'hydrate'\r\n key: string\r\n userId?: string\r\n success: boolean\r\n error?: string\r\n}\r\n\r\nlet _auditLogger: ((entry: AuditEntry) => void) | null = null\r\n\r\n/**\r\n * Configures the global audit logger\r\n * @param logger Callback for audit entries\r\n */\r\nexport const setAuditLogger = (logger: (entry: AuditEntry) => void) => { _auditLogger = logger }\r\n\r\n/**\r\n * Checks if audit logging is currently active (has a logger configured)\r\n */\r\nexport const isAuditActive = () => _auditLogger !== null\r\n\r\n/**\r\n * Records an audit entry\r\n * @param entry Entry to log\r\n */\r\nexport const logAudit = (entry: AuditEntry) => { if (_auditLogger) _auditLogger(entry) }\r\n\r\n// --- ENTERPRISE SECURITY SYSTEM ---\r\n\r\n/**\r\n * Permission levels for Role-Based Access Control\r\n */\r\nexport type Permission = 'read' | 'write' | 'delete' | 'admin'\r\n\r\n/**\r\n * Access control rules\r\n */\r\nexport interface AccessRule {\r\n /** Regex pattern for matching keys, or a function for dynamic checks */\r\n pattern: string | ((key: string, userId?: string) => boolean)\r\n /** Permissions granted by this rule */\r\n permissions: Permission[]\r\n}\r\n\r\n/**\r\n * Global access rules registry\r\n * Supports both string patterns and function-based rules\r\n */\r\nexport type AccessRulesMap = Map<string | ((key: string, userId?: string) => boolean), Permission[]>\r\n\r\n/**\r\n * Adds an access rule for a key pattern\r\n * @param rules Map of rules to update\r\n * @param pattern Regex pattern or function for keys\r\n * @param perms Allowed permissions\r\n */\r\nexport const addAccessRule = (rules: AccessRulesMap, pattern: string | ((key: string, userId?: string) => boolean), perms: Permission[]) => {\r\n rules.set(pattern instanceof RegExp ? pattern.source : pattern, perms)\r\n}\r\n\r\n/**\r\n * Checks if a user has permission for an action on a key\r\n * @param rules Map of access rules\r\n * @param key Store key\r\n * @param action Requested action\r\n * @param _userId User identifier (optional)\r\n * @returns boolean - True if permission granted\r\n */\r\nexport const hasPermission = (rules: AccessRulesMap, key: string, action: Permission, _userId?: string): boolean => {\r\n // Default allow ONLY if no rules are defined at all\r\n if (rules.size === 0) return true\r\n\r\n // Check each rule pattern\r\n for (const [pattern, perms] of rules) {\r\n let matches: boolean\r\n\r\n // Check if pattern is a function\r\n if (typeof pattern === 'function') {\r\n matches = pattern(key, _userId)\r\n } else {\r\n // It's a regex string\r\n try {\r\n matches = new RegExp(pattern).test(key)\r\n } catch {\r\n // Invalid regex, skip\r\n continue\r\n }\r\n }\r\n\r\n if (matches) {\r\n // User has permission if requested action is in allowed permissions\r\n // Or if 'admin' permission is granted (full access)\r\n return perms.includes(action) || perms.includes('admin')\r\n }\r\n }\r\n\r\n // No matching rule found but rules EXIST = default DENY (Fail-Closed)\r\n return false\r\n}\r\n\r\n/**\r\n * Sanitizes values against common XSS patterns.\r\n * WARNING: While this provides a baseline defense, for applications requiring\r\n * high-security HTML sanitization, consider using an external library like DOMPurify.\r\n * @param value Value to sanitize\r\n * @returns Sanitized value\r\n */\r\nexport const sanitizeValue = (value: unknown): unknown => {\r\n if (typeof value === 'string') {\r\n // First, decode HTML entities to catch encoded schemes like javascript:\r\n // This must happen BEFORE scheme checks to catch encoded attacks\r\n let decoded = value.replace(/&#[xX]?[0-9a-fA-F]+;?/g, (match) => {\r\n // Decode HTML entity to character\r\n const hexMatch = match.match(/&#x([0-9a-fA-F]+);?/i)\r\n if (hexMatch && hexMatch[1]) {\r\n return String.fromCharCode(parseInt(hexMatch[1], 16))\r\n }\r\n const decMatch = match.match(/&#([0-9]+);?/)\r\n if (decMatch && decMatch[1]) {\r\n return String.fromCharCode(parseInt(decMatch[1], 10))\r\n }\r\n return ''\r\n })\r\n\r\n // Also decode URL-encoded characters to catch %6Aavascript: style bypasses\r\n try {\r\n decoded = decodeURIComponent(decoded)\r\n } catch {\r\n // Invalid URL encoding, continue with original\r\n }\r\n\r\n // Now check for dangerous URL schemes with word boundary (\\b) to prevent partial matches\r\n // The scheme must be at word boundary to avoid matching \"somejavascript:\" incorrectly\r\n const schemeCheck = decoded.replace(/\\b(javascript|vbscript|data:text\\/html|about:blank|chrome:)/gi, '[SEC-REMOVED]')\r\n\r\n // Prevent XSS vectors using a more robust script tag pattern\r\n return schemeCheck\r\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\s*\\/\\s*script\\b[^>]*>/gi, '[SEC-REMOVED]')\r\n .replace(/on\\w+\\s*=/gi, '[SEC-REMOVED]=')\r\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '[SEC-REMOVED]')\r\n .replace(/<object\\b[^<]*(?:(?!<\\/object>)<[^<]*)*<\\/object>/gi, '[SEC-REMOVED]')\r\n .replace(/<embed\\b[^<]*(?:(?!<\\/embed>)<[^<]*)*<\\/embed>/gi, '[SEC-REMOVED]')\r\n .replace(/<svg\\b[^<]*(?:(?!<\\/svg>)<[^<]*)*<\\/svg>/gi, '[SEC-REMOVED]')\r\n .replace(/<form\\b[^<]*(?:(?!<\\/form>)<[^<]*)*<\\/form>/gi, '[SEC-REMOVED]')\r\n .replace(/<base\\b[^<]*(?:(?!<\\/base>)<[^<]*)*<\\/base>/gi, '[SEC-REMOVED]')\r\n .replace(/<link\\b[^<]*(?:(?!<\\/link>)<[^<]*)*<\\/link>/gi, '[SEC-REMOVED]')\r\n .replace(/<meta\\b[^<]*(?:(?!<\\/meta>)<[^<]*)*<\\/meta>/gi, '[SEC-REMOVED]')\r\n .replace(/<style\\b[^<]*(?:(?!<\\/style>)<[^<]*)*<\\/style>/gi, '[SEC-REMOVED]')\r\n }\r\n\r\n // Deep clone and sanitize nested objects\r\n if (value && typeof value === 'object' && !Array.isArray(value)) {\r\n // Check if it's a plain object or something else (like Date, Map, etc.)\r\n if (Object.getPrototypeOf(value) === Object.prototype) {\r\n const sanitized: Record<string, unknown> = {}\r\n for (const [k, v] of Object.entries(value)) {\r\n sanitized[k] = sanitizeValue(v)\r\n }\r\n return sanitized\r\n }\r\n return value // For non-plain objects, we return as is (security should be handled at the source)\r\n }\r\n\r\n // Array sanitization\r\n if (Array.isArray(value)) {\r\n return value.map(v => sanitizeValue(v))\r\n }\r\n\r\n // Primitive values\r\n return value\r\n}\r\n\r\n/**\r\n * Validates store key format and length\r\n * @param key Key to validate\r\n * @returns boolean - True if valid\r\n */\r\nexport const validateKey = (key: string): boolean => /^[a-zA-Z0-9_.-]+$/.test(key) && key.length <= 256\r\n\r\n// --- GDPR COMPLIANCE ---\r\n\r\nexport interface ConsentRecord { id: string, purpose: string, granted: boolean, timestamp: number }\r\nexport type ConsentsMap = Map<string, ConsentRecord[]>\r\n\r\n/**\r\n * Records user consent for a specific purpose\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @param purpose Purpose of data processing\r\n * @param granted Whether consent is granted\r\n * @returns ConsentRecord\r\n */\r\nexport const recordConsent = (consents: ConsentsMap, userId: string, purpose: string, granted: boolean): ConsentRecord => {\r\n const\r\n record = { id: crypto.randomUUID(), purpose, granted, timestamp: Date.now() },\r\n user = consents.get(userId) || []\r\n\r\n user.push(record)\r\n consents.set(userId, user)\r\n\r\n logAudit({ timestamp: Date.now(), action: 'set', key: `consent:${purpose}`, userId, success: true })\r\n\r\n return record\r\n}\r\n\r\n/**\r\n * Checks if a user has granted consent for a purpose\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @param purpose Purpose to check\r\n * @returns boolean\r\n */\r\nexport const hasConsent = (consents: ConsentsMap, userId: string, purpose: string): boolean => {\r\n const userConsents = consents.get(userId)\r\n if (!userConsents) return false\r\n\r\n // Find the latest record for this purpose (insertion order is reliable)\r\n for (let i = userConsents.length - 1; i >= 0; i--) {\r\n const record = userConsents[i]\r\n if (record && record.purpose === purpose) {\r\n return record.granted\r\n }\r\n }\r\n\r\n return false\r\n}\r\n\r\n/**\r\n * Revokes user consent for a specific purpose\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @param purpose Purpose of data processing\r\n * @returns ConsentRecord | null\r\n */\r\nexport const revokeConsent = (consents: ConsentsMap, userId: string, purpose: string): ConsentRecord | null => {\r\n return recordConsent(consents, userId, purpose, false)\r\n}\r\n\r\n/**\r\n * Retrieves all consent records for a user\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @returns ConsentRecord[]\r\n */\r\nexport const getConsents = (consents: ConsentsMap, userId: string) => consents.get(userId) || []\r\n\r\n/**\r\n * Exports all data associated with a user\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @returns Exported data object\r\n */\r\nexport const exportUserData = (consents: ConsentsMap, userId: string) => ({ userId, exportedAt: Date.now(), consents: consents.get(userId) || [] })\r\n\r\n/**\r\n * Deletes all user data (Right to be Forgotten)\r\n * @param consents Map of consents\r\n * @param userId User identifier\r\n * @returns Result status\r\n */\r\nexport const deleteUserData = (consents: ConsentsMap, userId: string) => {\r\n const count = consents.get(userId)?.length || 0\r\n consents.delete(userId)\r\n\r\n return { success: true, deletedConsents: count }\r\n}\r\n", "/**\r\n * Utility functions for the store.\r\n * Extracted from store.ts to reduce file size.\r\n */\r\n\r\n/**\r\n * Deep clone using structuredClone (native) with fallback.\r\n * Handles circular references safely and preserves common types.\r\n * @param obj - Object to clone\r\n * @returns Deep cloned object\r\n */\r\nexport const deepClone = <T>(obj: T): T => {\r\n if (obj === null || typeof obj !== 'object') return obj\r\n\r\n // Optimization: use native structuredClone if available\r\n if (typeof structuredClone === 'function') {\r\n try {\r\n return structuredClone(obj)\r\n } catch (_e) {\r\n // Fallback for non-serializable objects (functions, prototypes, etc.)\r\n }\r\n }\r\n\r\n const seen = new WeakMap<object, unknown>()\r\n\r\n const clone = <V>(value: V): V => {\r\n if (value === null || typeof value !== 'object') return value\r\n if (typeof value === 'function') return value as unknown as V // Functions cannot be deep cloned easily\r\n\r\n // Check for circular references\r\n if (seen.has(value as object)) return seen.get(value as object) as V\r\n\r\n if (value instanceof Date) return new Date(value.getTime()) as unknown as V\r\n if (value instanceof RegExp) return new RegExp(value.source, value.flags) as unknown as V\r\n if (value instanceof Map) {\r\n const result = new Map()\r\n seen.set(value as object, result)\r\n value.forEach((v, k) => result.set(clone(k), clone(v)))\r\n return result as unknown as V\r\n }\r\n if (value instanceof Set) {\r\n const result = new Set()\r\n seen.set(value as object, result)\r\n value.forEach((v) => result.add(clone(v)))\r\n return result as unknown as V\r\n }\r\n\r\n // Handle Plain Objects and Arrays\r\n const result = (Array.isArray(value)\r\n ? []\r\n : Object.create(Object.getPrototypeOf(value))) as Record<string | symbol, unknown>\r\n\r\n seen.set(value as object, result)\r\n\r\n const keys = [...Object.keys(value as object), ...Object.getOwnPropertySymbols(value as object)]\r\n for (const key of keys) {\r\n result[key as string] = clone((value as Record<string | symbol, unknown>)[key])\r\n }\r\n\r\n return result as V\r\n }\r\n\r\n return clone(obj)\r\n}\r\n\r\n/**\r\n * Compares two values for deep equality.\r\n * @param a - First value\r\n * @param b - Second value\r\n * @returns True if values are equal\r\n */\r\nexport const isEqual = (a: unknown, b: unknown): boolean => {\r\n if (a === b) return true\r\n if (a === null || b === null) return a === b\r\n if (typeof a !== 'object' || typeof b !== 'object') return a === b\r\n if (Array.isArray(a) && Array.isArray(b)) {\r\n if (a.length !== b.length) return false\r\n for (let i = 0; i < a.length; i++) if (!isEqual(a[i], b[i])) return false\r\n return true\r\n }\r\n const keysA = Object.keys(a as object)\r\n const keysB = Object.keys(b as object)\r\n if (keysA.length !== keysB.length) return false\r\n\r\n for (let i = 0; i < keysA.length; i++) {\r\n const key = keysA[i] as string\r\n if (!(key in (b as object)) || !isEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) return false\r\n }\r\n return true\r\n}\r\n", "import { StorageAdapters } from \"./store\"\r\nimport * as Security from \"./security\"\r\nimport { deepClone } from \"./utils\"\r\nimport type { StoreConfig, PersistOptions } from \"./types\"\r\nimport { produce as _immerProduce, freeze as _immerFreeze } from 'immer'\r\n\r\n/**\r\n * Enterprise-grade persistence layer for RGS store.\r\n * Handles serialization, encryption, and storage adapter abstraction.\r\n */\r\n\r\n// Helper to get prefix\r\nconst _getPrefix = (namespace: string) => `${namespace}_`\r\n\r\nexport interface PersistenceContext {\r\n store: Map<string, unknown>\r\n versions: Map<string, number>\r\n sizes: Map<string, number>\r\n totalSize: number\r\n storage: ReturnType<typeof StorageAdapters.local>\r\n config: StoreConfig<Record<string, unknown>>\r\n diskQueue: Map<string, { value: unknown, options: PersistOptions }>\r\n encryptionKey: Security.EncryptionKey | null\r\n audit: (action: 'set' | 'get' | 'delete' | 'hydrate', key: string, success: boolean, error?: string) => void\r\n onError?: (error: Error, metadata?: Record<string, unknown>) => void\r\n silent: boolean\r\n debounceTime: number\r\n currentVersion: number\r\n}\r\n\r\n\r\n/**\r\n * Flushes the disk queue to persistent storage.\r\n */\r\nexport const flushDisk = async (ctx: PersistenceContext) => {\r\n if (!ctx.storage) return\r\n\r\n const { store, config, diskQueue, storage, encryptionKey, audit, onError, silent, currentVersion } = ctx\r\n const prefix = _getPrefix(config.namespace || 'gstate')\r\n\r\n // Save entire state under namespace key for simpler loading if needed by some adapters\r\n // This logic seems redundant if we save individual keys, but was in original store. keeping for compatibility.\r\n try {\r\n const stateObj: Record<string, unknown> = {}\r\n store.forEach((v, k) => { stateObj[k] = v })\r\n\r\n let dataValue: unknown\r\n const isEncoded = config?.encoded\r\n if (isEncoded) {\r\n dataValue = btoa(JSON.stringify(stateObj))\r\n } else {\r\n dataValue = JSON.stringify(stateObj)\r\n }\r\n\r\n storage.setItem(prefix.replace('_', ''), JSON.stringify({\r\n v: 1, t: Date.now(), e: null,\r\n d: dataValue, _sys_v: currentVersion, _b64: isEncoded ? true : undefined\r\n }))\r\n audit('set', 'FULL_STATE', true)\r\n } catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (onError) onError(error, { operation: 'persist', key: 'FULL_STATE' })\r\n else if (!silent) console.error(`[gState] Persist failed: `, error)\r\n }\r\n\r\n const queue = Array.from(diskQueue.entries()); diskQueue.clear()\r\n for (const [key, data] of queue) {\r\n try {\r\n let dataValue: unknown = data.value\r\n const isEncoded = data.options.encoded || data.options.secure\r\n if (data.options.encrypted) {\r\n if (!encryptionKey) throw new Error(`Encryption key missing for \"${key}\"`)\r\n dataValue = await Security.encrypt(data.value, encryptionKey)\r\n } else if (isEncoded) {\r\n dataValue = btoa(JSON.stringify(data.value))\r\n } else if (typeof data.value === 'object' && data.value !== null) {\r\n dataValue = JSON.stringify(data.value)\r\n }\r\n\r\n storage.setItem(`${prefix}${key}`, JSON.stringify({\r\n v: (ctx.versions.get(key) || 1), t: Date.now(), e: data.options.ttl ? Date.now() + data.options.ttl : null,\r\n d: dataValue, _sys_v: currentVersion, _enc: data.options.encrypted ? true : undefined, _b64: isEncoded ? true : undefined\r\n }))\r\n audit('set', key, true)\r\n } catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (onError) onError(error, { operation: 'persist', key })\r\n else if (!silent) console.error(`[gState] Persist failed: `, error)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Hydrates the store from persistent storage.\r\n */\r\nexport const hydrateStore = async (\r\n ctx: PersistenceContext,\r\n calculateSize: (val: unknown) => number,\r\n emit: () => void\r\n): Promise<void> => {\r\n const { storage, config, encryptionKey, audit, onError, silent, currentVersion, store, sizes, versions } = ctx\r\n const prefix = _getPrefix(config.namespace || 'gstate')\r\n const immer = config.immer ?? true\r\n\r\n if (!storage) return\r\n\r\n try {\r\n const persisted: Record<string, unknown> = {}\r\n let savedV = 0\r\n for (let i = 0; i < (storage.length || 0); i++) {\r\n const k = storage.key(i)\r\n if (!k || !k.startsWith(prefix)) continue\r\n const raw = storage.getItem(k)\r\n if (!raw) continue\r\n try {\r\n const meta = JSON.parse(raw), key = k.substring(prefix.length)\r\n\r\n // Version fallback for older stores where _sys_v was v\r\n savedV = Math.max(savedV, meta._sys_v !== undefined ? meta._sys_v : (meta.v || 0))\r\n\r\n if (meta.e && Date.now() > meta.e) { storage.removeItem(k); i--; continue }\r\n let d = meta.d\r\n if (meta._enc && encryptionKey) {\r\n d = await Security.decrypt(d, encryptionKey)\r\n } else if (typeof d === \"string\") {\r\n if (meta._b64) { try { d = JSON.parse(atob(d)) } catch (_e) { } }\r\n else if (d.startsWith(\"{\") || d.startsWith(\"[\")) { try { d = JSON.parse(d) } catch (_e) { } }\r\n }\r\n persisted[key] = d; audit('hydrate', key, true)\r\n } catch (err) {\r\n audit('hydrate', k, false, String(err))\r\n const error = err instanceof Error ? err : new Error(String(err))\r\n if (onError) onError(error, { operation: 'hydration', key: k })\r\n else if (!silent) console.error(`[gState] Hydration failed for \"${k}\": `, err)\r\n }\r\n }\r\n const final = (savedV < currentVersion && config.migrate) ? config.migrate(persisted, savedV) : persisted\r\n\r\n Object.entries(final).forEach(([k, v]) => {\r\n // Re-freeze loaded state if immer is enabled\r\n const frozen = (immer && v !== null && typeof v === 'object') ? _immerFreeze(deepClone(v as object), true) : v\r\n\r\n const size = calculateSize(frozen)\r\n const oldSize = sizes.get(k) || 0\r\n ctx.totalSize = ctx.totalSize - oldSize + size\r\n sizes.set(k, size)\r\n store.set(k, frozen); versions.set(k, 1)\r\n })\r\n emit()\r\n } catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (onError) onError(error, { operation: 'hydration' })\r\n else if (!silent) console.error(`[gState] Hydration failed: `, error)\r\n }\r\n}\r\n", "import { IStore, PluginHookName, PluginContext, IPlugin } from \"./types\"\r\n\r\n/**\r\n * Manages plugins and their lifecycle hooks.\r\n */\r\n\r\nexport interface PluginManagerContext<S extends Record<string, unknown>> {\r\n plugins: Map<string, IPlugin<S>>\r\n onError?: (error: Error, metadata?: Record<string, unknown>) => void\r\n silent: boolean\r\n}\r\n\r\nexport const runHook = <S extends Record<string, unknown>>(\r\n ctx: PluginManagerContext<S>,\r\n name: PluginHookName,\r\n hookContext: PluginContext<S>\r\n) => {\r\n if (ctx.plugins.size === 0) return\r\n for (const p of ctx.plugins.values()) {\r\n const hook = p.hooks?.[name]\r\n if (hook) {\r\n try { hook(hookContext) }\r\n catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (ctx.onError) ctx.onError(error, { operation: `plugin:${p.name}:${name}`, key: hookContext.key })\r\n else if (!ctx.silent) console.error(`[gState] Plugin \"${p.name}\" error:`, e)\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport const installPlugin = <S extends Record<string, unknown>>(\r\n ctx: PluginManagerContext<S>,\r\n plugin: IPlugin<S>,\r\n storeInstance: IStore<S>\r\n) => {\r\n try {\r\n ctx.plugins.set(plugin.name, plugin)\r\n plugin.hooks?.onInstall?.({ store: storeInstance })\r\n } catch (e) {\r\n const error = e instanceof Error ? e : new Error(String(e))\r\n if (ctx.onError) ctx.onError(error, { operation: 'plugin:install', key: plugin.name })\r\n else if (!ctx.silent) console.error(`[gState] Failed to install plugin \"${plugin.name}\": `, e)\r\n }\r\n}\r\n", "import { IStore } from \"./types\"\r\nimport { deepClone } from \"./utils\"\r\nimport { freeze as _immerFreeze } from 'immer'\r\n\r\n/**\r\n * Local-First Sync Engine for RGS\r\n *\r\n * Provides offline-by-default functionality with automatic synchronization\r\n * when connectivity is restored. Supports multiple conflict resolution strategies.\r\n */\r\n\r\n// --- Types ---\r\n\r\nexport type SyncStrategy = 'last-write-wins' | 'merge' | 'crdt' | 'server-wins' | 'client-wins'\r\n\r\nexport interface SyncConfig {\r\n /** Remote endpoint for synchronization */\r\n endpoint: string\r\n /** Authentication token */\r\n authToken?: string\r\n /** Conflict resolution strategy (default: 'last-write-wins') */\r\n strategy?: SyncStrategy\r\n /** Auto-sync interval in ms (default: 30000 = 30s) */\r\n autoSyncInterval?: number\r\n /** Enable auto-sync on reconnect (default: true) */\r\n syncOnReconnect?: boolean\r\n /** Debounce time for batch sync (default: 1000ms) */\r\n debounceTime?: number\r\n /** Custom fetch function */\r\n fetch?: typeof fetch\r\n /** Callback on sync complete */\r\n onSync?: (result: SyncResult) => void\r\n /** Callback on conflict */\r\n onConflict?: (conflict: ConflictInfo) => ConflictResolution\r\n /** Maximum retries on failure (default: 3) */\r\n maxRetries?: number\r\n}\r\n\r\nexport interface SyncResult {\r\n success: boolean\r\n syncedKeys: string[]\r\n conflicts: ConflictInfo[]\r\n errors: string[]\r\n timestamp: number\r\n duration: number\r\n}\r\n\r\nexport interface ConflictInfo {\r\n key: string\r\n localValue: unknown\r\n remoteValue: unknown\r\n localVersion: number\r\n remoteVersion: number\r\n timestamp: number\r\n}\r\n\r\nexport type ConflictResolution =\r\n | { action: 'accept-local' }\r\n | { action: 'accept-remote' }\r\n | { action: 'merge'; value: unknown }\r\n | { action: 'discard' }\r\n\r\nexport interface SyncState {\r\n isOnline: boolean\r\n isSyncing: boolean\r\n lastSyncTimestamp: number | null\r\n pendingChanges: number\r\n conflicts: number\r\n}\r\n\r\n// --- Sync Engine ---\r\n\r\ninterface PendingChange {\r\n key: string\r\n value: unknown\r\n timestamp: number\r\n version: number\r\n}\r\n\r\ninterface RemoteVersion {\r\n version: number\r\n timestamp: number\r\n value: unknown\r\n}\r\n\r\nexport class SyncEngine<S extends Record<string, unknown> = Record<string, unknown>> {\r\n private store: IStore<S>\r\n private config: Required<SyncConfig>\r\n private pendingQueue: Map<string, PendingChange> = new Map()\r\n private remoteVersions: Map<string, RemoteVersion> = new Map()\r\n private syncTimer: ReturnType<typeof setTimeout> | null = null\r\n private onlineStatusListeners: Set<(online: boolean) => void> = new Set()\r\n private syncStateListeners: Set<(state: SyncState) => void> = new Set()\r\n private _isOnline: boolean = true\r\n private _isSyncing: boolean = false\r\n\r\n constructor(store: IStore<S>, config: SyncConfig) {\r\n this.store = store\r\n this.config = {\r\n endpoint: config.endpoint,\r\n authToken: config.authToken || '',\r\n strategy: config.strategy || 'last-write-wins',\r\n autoSyncInterval: config.autoSyncInterval ?? 30000,\r\n syncOnReconnect: config.syncOnReconnect ?? true,\r\n debounceTime: config.debounceTime ?? 1000,\r\n fetch: config.fetch || fetch,\r\n onSync: config.onSync || (() => { }),\r\n onConflict: config.onConflict || (() => ({ action: 'accept-local' })),\r\n maxRetries: config.maxRetries ?? 3\r\n }\r\n\r\n this._isOnline = typeof navigator !== 'undefined' ? navigator.onLine : true\r\n this._setupOnlineListener()\r\n this._setupStoreListener()\r\n\r\n // Start auto-sync if enabled\r\n if (this.config.autoSyncInterval > 0) {\r\n this._startAutoSync()\r\n }\r\n }\r\n\r\n private _setupOnlineListener(): void {\r\n if (typeof window === 'undefined') return\r\n\r\n window.addEventListener('online', () => {\r\n this._isOnline = true\r\n this._notifyOnlineChange(true)\r\n if (this.config.syncOnReconnect) {\r\n this.sync()\r\n }\r\n })\r\n\r\n window.addEventListener('offline', () => {\r\n this._isOnline = false\r\n this._notifyOnlineChange(false)\r\n })\r\n }\r\n\r\n private _setupStoreListener(): void {\r\n // Listen to all store changes to queue for sync\r\n this.store._subscribe(() => {\r\n // This will be called on every change - we track pending changes differently\r\n })\r\n }\r\n\r\n private _startAutoSync(): void {\r\n setInterval(() => {\r\n if (this._isOnline && !this._isSyncing && this.pendingQueue.size > 0) {\r\n this.sync()\r\n }\r\n }, this.config.autoSyncInterval)\r\n }\r\n\r\n private _notifyOnlineChange(online: boolean): void {\r\n this.onlineStatusListeners.forEach(cb => cb(online))\r\n this._notifyStateChange()\r\n }\r\n\r\n private _notifyStateChange(): void {\r\n const state = this.getState()\r\n this.syncStateListeners.forEach(cb => cb(state))\r\n }\r\n\r\n /**\r\n * Queue a change for synchronization\r\n */\r\n queueChange(key: string, value: unknown): void {\r\n const version = this.store._getVersion(key) || 1\r\n this.pendingQueue.set(key, {\r\n key,\r\n value: deepClone(value),\r\n timestamp: Date.now(),\r\n version\r\n })\r\n this._notifyStateChange()\r\n\r\n // Debounced sync\r\n if (this.syncTimer) clearTimeout(this.syncTimer)\r\n this.syncTimer = setTimeout(() => {\r\n if (this._isOnline) this.sync()\r\n }, this.config.debounceTime)\r\n }\r\n\r\n /**\r\n * Perform synchronization with remote server\r\n */\r\n async sync(): Promise<SyncResult> {\r\n if (this._isSyncing) {\r\n return {\r\n success: false,\r\n syncedKeys: [],\r\n conflicts: [],\r\n errors: ['Sync already in progress'],\r\n timestamp: Date.now(),\r\n duration: 0\r\n }\r\n }\r\n\r\n this._isSyncing = true\r\n this._notifyStateChange()\r\n\r\n const startTime = Date.now()\r\n const syncedKeys: string[] = []\r\n const conflicts: ConflictInfo[] = []\r\n const errors: string[] = []\r\n\r\n try {\r\n // Get pending changes\r\n const pendingChanges = Array.from(this.pendingQueue.values())\r\n\r\n if (pendingChanges.length === 0) {\r\n this._isSyncing = false\r\n this._notifyStateChange()\r\n return {\r\n success: true,\r\n syncedKeys: [],\r\n conflicts: [],\r\n errors: [],\r\n timestamp: Date.now(),\r\n duration: Date.now() - startTime\r\n }\r\n }\r\n\r\n // Fetch remote versions for conflict detection\r\n await this._fetchRemoteVersions(pendingChanges.map(p => p.key))\r\n\r\n // Process each change\r\n for (const change of pendingChanges) {\r\n try {\r\n const remoteVersion = this.remoteVersions.get(change.key)\r\n\r\n if (!remoteVersion) {\r\n // No remote version - first time sync, just push\r\n await this._pushChange(change)\r\n syncedKeys.push(change.key)\r\n this.pendingQueue.delete(change.key)\r\n } else if (remoteVersion.version >= change.version) {\r\n // Remote is newer - conflict!\r\n const conflict: ConflictInfo = {\r\n key: change.key,\r\n localValue: change.value,\r\n remoteValue: remoteVersion.value,\r\n localVersion: change.version,\r\n remoteVersion: remoteVersion.version,\r\n timestamp: change.timestamp\r\n }\r\n conflicts.push(conflict)\r\n\r\n // Resolve conflict\r\n const resolution = this.config.onConflict(conflict)\r\n await this._resolveConflict(change, remoteVersion, resolution)\r\n syncedKeys.push(change.key)\r\n this.pendingQueue.delete(change.key)\r\n } else {\r\n // Local is newer - push to remote\r\n await this._pushChange(change)\r\n syncedKeys.push(change.key)\r\n this.pendingQueue.delete(change.key)\r\n }\r\n } catch (err) {\r\n errors.push(`Failed to sync \"${change.key}\": ${err}`)\r\n }\r\n }\r\n\r\n const result: SyncResult = {\r\n success: errors.length === 0,\r\n syncedKeys,\r\n conflicts,\r\n errors,\r\n timestamp: Date.now(),\r\n duration: Date.now() - startTime\r\n }\r\n\r\n this.config.onSync(result)\r\n return result\r\n } catch (err) {\r\n const errorMsg = `Sync failed: ${err}`\r\n errors.push(errorMsg)\r\n\r\n return {\r\n success: false,\r\n syncedKeys,\r\n conflicts,\r\n errors,\r\n timestamp: Date.now(),\r\n duration: Date.now() - startTime\r\n }\r\n } finally {\r\n this._isSyncing = false\r\n this._notifyStateChange()\r\n }\r\n }\r\n\r\n private async _fetchRemoteVersions(keys: string[]): Promise<void> {\r\n try {\r\n const response = await this.config.fetch(`${this.config.endpoint}/versions`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(this.config.authToken && { 'Authorization': `Bearer ${this.config.authToken}` })\r\n },\r\n body: JSON.stringify({ keys })\r\n })\r\n\r\n if (response.ok) {\r\n const data = await response.json()\r\n if (data.versions) {\r\n for (const [key, version] of Object.entries(data.versions)) {\r\n this.remoteVersions.set(key, version as RemoteVersion)\r\n }\r\n }\r\n }\r\n } catch (err) {\r\n console.warn('[SyncEngine] Failed to fetch remote versions:', err)\r\n }\r\n }\r\n\r\n private async _pushChange(change: PendingChange): Promise<void> {\r\n let retries = 0\r\n\r\n while (retries < this.config.maxRetries) {\r\n try {\r\n const response = await this.config.fetch(`${this.config.endpoint}/sync`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(this.config.authToken && { 'Authorization': `Bearer ${this.config.authToken}` })\r\n },\r\n body: JSON.stringify({\r\n key: change.key,\r\n value: change.value,\r\n version: change.version,\r\n timestamp: change.timestamp\r\n })\r\n })\r\n\r\n if (response.ok) {\r\n const data = await response.json()\r\n if (data.version) {\r\n this.remoteVersions.set(change.key, {\r\n version: data.version,\r\n timestamp: data.timestamp || Date.now(),\r\n value: change.value\r\n })\r\n }\r\n return\r\n }\r\n\r\n retries++\r\n } catch (err) {\r\n retries++\r\n if (retries >= this.config.maxRetries) throw err\r\n }\r\n }\r\n }\r\n\r\n private async _resolveConflict(\r\n localChange: PendingChange,\r\n remoteVersion: RemoteVersion,\r\n resolution: ConflictResolution\r\n ): Promise<void> {\r\n switch (resolution.action) {\r\n case 'accept-local':\r\n // Force push local value\r\n await this._pushChange({\r\n ...localChange,\r\n version: remoteVersion.version + 1,\r\n timestamp: Date.now()\r\n })\r\n break\r\n\r\n case 'accept-remote':\r\n // Keep remote value, update local store\r\n this.store.set(localChange.key, remoteVersion.value)\r\n break\r\n\r\n case 'merge':\r\n // Use merged value\r\n this.store.set(localChange.key, resolution.value)\r\n await this._pushChange({\r\n key: localChange.key,\r\n value: resolution.value,\r\n version: Math.max(localChange.version, remoteVersion.version) + 1,\r\n timestamp: Date.now()\r\n })\r\n break\r\n\r\n case 'discard':\r\n // Do nothing, keep local but don't sync\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * Get current sync state\r\n */\r\n getState(): SyncState {\r\n return {\r\n isOnline: this._isOnline,\r\n isSyncing: this._isSyncing,\r\n lastSyncTimestamp: null, // Could track this\r\n pendingChanges: this.pendingQueue.size,\r\n conflicts: 0 // Could track unresolved conflicts\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to online status changes\r\n */\r\n onOnlineChange(callback: (online: boolean) => void): () => void {\r\n this.onlineStatusListeners.add(callback)\r\n return () => this.onlineStatusListeners.delete(callback)\r\n }\r\n\r\n /**\r\n * Subscribe to sync state changes\r\n */\r\n onStateChange(callback: (state: SyncState) => void): () => void {\r\n this.syncStateListeners.add(callback)\r\n return () => this.syncStateListeners.delete(callback)\r\n }\r\n\r\n /**\r\n * Force push all pending changes\r\n */\r\n async flush(): Promise<SyncResult> {\r\n return this.sync()\r\n }\r\n\r\n /**\r\n * Destroy the sync engine\r\n */\r\n destroy(): void {\r\n if (this.syncTimer) clearTimeout(this.syncTimer)\r\n this.pendingQueue.clear()\r\n this.onlineStatusListeners.clear()\r\n this.syncStateListeners.clear()\r\n }\r\n}\r\n\r\n/**\r\n * Create a configured SyncEngine instance\r\n */\r\nexport const createSyncEngine = <S extends Record<string, unknown>>(\r\n store: IStore<S>,\r\n config: SyncConfig\r\n): SyncEngine<S> => {\r\n return new SyncEngine(store, config)\r\n}\r\n", "import { useSyncExternalStore, useDebugValue, useMemo, useCallback, useEffect, useState } from \"react\"\r\nimport { createStore } from \"./store\"\r\nimport type { IStore, StoreConfig, PersistOptions, StateUpdater } from \"./types\"\r\nimport { SyncEngine, SyncConfig, SyncState } from \"./sync\"\r\n\r\nlet _defaultStore: IStore<Record<string, unknown>> | null = null\r\n\r\n/**\r\n * Initialize a global store instance.\r\n * @param config Optional store configuration\r\n * @returns IStore instance\r\n * @throws Error if store already exists (prevents accidental overwrites)\r\n */\r\nexport const initState = <S extends Record<string, unknown>>(\r\n config?: StoreConfig<S>\r\n): IStore<S> => {\r\n if (_defaultStore && !config?.namespace) {\r\n if (!config?.silent) {\r\n console.warn(\r\n \"[gState] Store already exists. Pass a unique namespace to create additional stores.\"\r\n )\r\n }\r\n }\r\n\r\n const store = createStore<S>(config)\r\n _defaultStore = store as IStore<Record<string, unknown>>\r\n return store\r\n}\r\n\r\n/**\r\n * Cleanup the global state.\r\n * Safe to call multiple times.\r\n */\r\nexport const destroyState = (): void => {\r\n if (_defaultStore) {\r\n _defaultStore.destroy()\r\n _defaultStore = null\r\n }\r\n}\r\n\r\n/**\r\n * Hook to check if the store has finished hydration.\r\n * @param store Optional store instance\r\n * @returns boolean\r\n */\r\nexport const useIsStoreReady = (store?: IStore<Record<string, unknown>>): boolean => {\r\n const targetStore = store || _defaultStore\r\n\r\n const subscribe = useMemo(() =>\r\n (callback: () => void) => targetStore ? targetStore._subscribe(callback) : () => { },\r\n [targetStore]\r\n )\r\n\r\n return useSyncExternalStore(\r\n subscribe,\r\n () => targetStore ? targetStore.isReady : false,\r\n () => true // SSR is always \"ready\" as it doesn't hydrate from local storage\r\n )\r\n}\r\n\r\n/**\r\n * Get the current default store (for advanced use cases).\r\n * Returns null if no store has been initialized.\r\n */\r\nexport const getStore = (): IStore<Record<string, unknown>> | null => _defaultStore\r\n\r\n/**\r\n * Check if running in a server-side environment.\r\n */\r\nconst _isServer = (): boolean =>\r\n typeof window === 'undefined' ||\r\n typeof window.document === 'undefined'\r\n\r\n/**\r\n * Reactive Hook for state management.\r\n *\r\n * Supports two modes:\r\n * 1. String Key: `useStore('count')` -> Returns [value, setter]\r\n * 2. Type-Safe Selector: `useStore(state => state.count)` -> Returns value (Read-only)\r\n */\r\nexport function useStore<T, S extends Record<string, unknown> = Record<string, unknown>>(\r\n selector: (state: S) => T,\r\n store?: IStore<S>\r\n): T\r\nexport function useStore<T = unknown, S extends Record<string, unknown> = Record<string, unknown>>(\r\n key: string,\r\n store?: IStore<S>\r\n): readonly [T | undefined, (val: T | StateUpdater<T>, options?: PersistOptions) => boolean]\r\nexport function useStore<T = unknown, S extends Record<string, unknown> = Record<string, unknown>>(\r\n keyOrSelector: string | ((state: S) => T),\r\n store?: IStore<S>\r\n): T | readonly [T | undefined, (val: T | StateUpdater<T>, options?: PersistOptions) => boolean] {\r\n // Memoize store reference\r\n const targetStore = useMemo(() =>\r\n (store || _defaultStore) as IStore<S> | null,\r\n [store]\r\n )\r\n\r\n // Ghost store fallback\r\n const ghostStore = useMemo(() => {\r\n const noop = () => { }\r\n const noopFalse = () => false\r\n const noopNull = () => null\r\n return {\r\n set: noopFalse, get: noopNull, remove: noopFalse, delete: noopFalse,\r\n deleteAll: noopFalse, list: () => ({}), compute: noopNull,\r\n watch: () => () => { }, use: noop, transaction: noop, destroy: noop,\r\n _subscribe: () => () => { }, _setSilently: noop, _registerMethod: noop,\r\n _addPlugin: noop, _removePlugin: noop, _getVersion: () => 0,\r\n get isReady() { return false }, whenReady: () => Promise.resolve(),\r\n get plugins() { return {} },\r\n getSnapshot: () => ({} as S), // Ghost snapshot\r\n get namespace() { return \"ghost\" }, get userId() { return undefined }\r\n } as unknown as IStore<S>\r\n }, [])\r\n\r\n const safeStore = targetStore || ghostStore\r\n\r\n const isSelector = typeof keyOrSelector === 'function'\r\n const key = !isSelector ? (keyOrSelector as string) : null\r\n const selector = isSelector ? (keyOrSelector as (state: S) => T) : null\r\n\r\n // 1. Subscribe\r\n const subscribe = useCallback(\r\n (callback: () => void) => {\r\n if (isSelector) {\r\n // Selector mode: subscribe to all changes\r\n return safeStore._subscribe(callback)\r\n } else {\r\n // Key mode: subscribe to key changes\r\n return safeStore._subscribe(callback, key!)\r\n }\r\n },\r\n [safeStore, isSelector, key]\r\n )\r\n\r\n // 2. Get Snapshot (Client)\r\n const getSnapshot = useCallback(() => {\r\n if (isSelector) {\r\n return selector!(safeStore.getSnapshot())\r\n } else {\r\n return safeStore.get<T>(key!) ?? undefined\r\n }\r\n }, [safeStore, isSelector, key, selector])\r\n\r\n // 3. Get Snapshot (Server)\r\n const getServerSnapshot = useCallback(() => {\r\n if (isSelector) {\r\n try { return selector!({} as S) } catch { return undefined }\r\n } else {\r\n return undefined\r\n }\r\n }, [selector, isSelector])\r\n\r\n const value = useSyncExternalStore(\r\n subscribe,\r\n getSnapshot as () => T | undefined, // Cast needed for union types\r\n getServerSnapshot as () => T | undefined\r\n )\r\n\r\n // 4. Setter (Only for Key Mode)\r\n const setter = useCallback(\r\n (val: T | StateUpdater<T>, options?: PersistOptions) => {\r\n if (isSelector) {\r\n if (process.env.NODE_ENV !== 'production') {\r\n console.warn('[gState] Cannot set value when using a selector.')\r\n }\r\n return false\r\n }\r\n return safeStore.set<T>(key!, val, options)\r\n },\r\n [safeStore, isSelector, key]\r\n )\r\n\r\n // Debug value\r\n useDebugValue(value, v => isSelector ? `Selector: ${JSON.stringify(v)}` : `${key}: ${JSON.stringify(v)}`)\r\n\r\n if (isSelector) {\r\n return value as T\r\n }\r\n\r\n return [value, setter] as const\r\n}\r\n\r\n// Store map for sync engines - using any to avoid complex generic issues\r\nconst _syncEngines = new Map<string, SyncEngine<Record<string, unknown>>>()\r\n\r\n/**\r\n * Initialize sync engine for a store\r\n * @param store - The store to sync\r\n * @param config - Sync configuration\r\n * @returns SyncEngine instance\r\n */\r\nexport const initSync = (\r\n store: IStore<Record<string, unknown>>,\r\n config: SyncConfig\r\n): SyncEngine<Record<string, unknown>> => {\r\n const key = store.namespace\r\n if (_syncEngines.has(key)) {\r\n console.warn(`[gState] Sync engine already exists for namespace \"${key}\". Call destroySync first.`)\r\n return _syncEngines.get(key)!\r\n }\r\n\r\n const engine = new SyncEngine(store, config)\r\n _syncEngines.set(key, engine)\r\n return engine\r\n}\r\n\r\n/**\r\n * Destroy sync engine for a namespace\r\n */\r\nexport const destroySync = (namespace: string): void => {\r\n const engine = _syncEngines.get(namespace)\r\n if (engine) {\r\n engine.destroy()\r\n _syncEngines.delete(namespace)\r\n }\r\n}\r\n\r\n/**\r\n * Hook for synchronized state management.\r\n * Provides offline-by-default functionality with automatic sync.\r\n *\r\n * @param key - State key\r\n * @param store - Optional store instance (uses default if not provided)\r\n * @returns [value, setter, syncState]\r\n *\r\n * @example\r\n * const [count, setCount, syncState] = useSyncedState('count')\r\n *\r\n * // syncState contains:\r\n * // - isOnline: boolean\r\n * // - isSyncing: boolean\r\n * // - pendingChanges: number\r\n * // - conflicts: number\r\n */\r\nexport function useSyncedState<T = unknown>(\r\n key: string,\r\n store?: IStore<Record<string, unknown>>\r\n): readonly [\r\n T | undefined,\r\n (val: T | StateUpdater<T>, options?: PersistOptions) => boolean,\r\n SyncState\r\n] {\r\n const targetStore = store || _defaultStore\r\n const namespace = targetStore?.namespace || 'default'\r\n\r\n // Get or create sync engine\r\n const engine = _syncEngines.get(namespace)\r\n\r\n // Use useStore with any cast to handle generics\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const result = useStore(key, targetStore as any) as readonly [T | undefined, (val: any, options?: PersistOptions) => boolean]\r\n const value = result[0] as T | undefined\r\n const setter = result[1]\r\n\r\n // Track sync state\r\n const [syncState, setSyncState] = useState<SyncState>(() => engine?.getState() || {\r\n isOnline: true,\r\n isSyncing: false,\r\n lastSyncTimestamp: null,\r\n pendingChanges: 0,\r\n conflicts: 0\r\n })\r\n\r\n // Subscribe to sync state changes\r\n useEffect(() => {\r\n if (!engine) return\r\n\r\n const unsubscribe = engine.onStateChange(setSyncState)\r\n return unsubscribe\r\n }, [engine])\r\n\r\n // Wrapper setter that queues changes for sync\r\n const syncedSetter = useCallback(\r\n (val: T | StateUpdater<T>, options?: PersistOptions) => {\r\n const result = setter(val, options)\r\n\r\n if (result && engine) {\r\n // Get the current value and queue for sync\r\n const currentValue = targetStore?.get(key)\r\n engine.queueChange(key, currentValue)\r\n }\r\n\r\n return result\r\n },\r\n [setter, engine, key, targetStore]\r\n )\r\n\r\n return [value, syncedSetter, syncState] as const\r\n}\r\n\r\n/**\r\n * Hook to get global sync status\r\n *\r\n * @example\r\n * const status = useSyncStatus()\r\n * // status.isOnline, status.isSyncing, status.pendingChanges\r\n */\r\nexport const useSyncStatus = (): SyncState => {\r\n const [state, setState] = useState<SyncState>({\r\n isOnline: true,\r\n isSyncing: false,\r\n lastSyncTimestamp: null,\r\n pendingChanges: 0,\r\n conflicts: 0\r\n })\r\n\r\n useEffect(() => {\r\n // Aggregate state from all sync engines\r\n const updateState = () => {\r\n let isOnline = true\r\n let isSyncing = false\r\n let pendingChanges = 0\r\n let conflicts = 0\r\n\r\n _syncEngines.forEach(engine => {\r\n const s = engine.getState()\r\n isOnline = isOnline && s.isOnline\r\n isSyncing = isSyncing || s.isSyncing\r\n pendingChanges += s.pendingChanges\r\n conflicts += s.conflicts\r\n })\r\n\r\n setState({\r\n isOnline,\r\n isSyncing,\r\n lastSyncTimestamp: null,\r\n pendingChanges,\r\n conflicts\r\n })\r\n }\r\n\r\n updateState()\r\n\r\n // Subscribe to all engines\r\n const unsubscribes = Array.from(_syncEngines.values()).map(engine =>\r\n engine.onStateChange(updateState)\r\n )\r\n\r\n return () => unsubscribes.forEach(fn => fn())\r\n }, [])\r\n\r\n return state\r\n}\r\n\r\n/**\r\n * Trigger manual sync for a specific namespace\r\n */\r\nexport const triggerSync = async (namespace?: string): Promise<void> => {\r\n const targetNamespace = namespace || _defaultStore?.namespace\r\n if (!targetNamespace) return\r\n\r\n const engine = _syncEngines.get(targetNamespace)\r\n if (engine) {\r\n await engine.flush()\r\n }\r\n}\r\n", "import { createStore } from \"./store\"\r\nimport type { IStore, AsyncState } from \"./types\"\r\n\r\n/**\r\n * Creates an async store that automatically manages the data/loading/error lifecycle.\r\n * @template T The type of data being fetched\r\n * @param resolver - Async function that returns the data\r\n * @param options - Configuration options\r\n * @returns Store instance with execute method\r\n *\r\n * @example\r\n * const store = createAsyncStore(async () => {\r\n * const response = await fetch('/api/data');\r\n * return response.json();\r\n * }, { key: 'userData', persist: true });\r\n *\r\n * // Execute the fetch\r\n * await store.execute();\r\n *\r\n * // Use in React\r\n * const { data, loading, error } = store.get('userData');\r\n */\r\nexport const createAsyncStore = <T>(\r\n resolver: () => Promise<T>,\r\n options?: { key?: string, persist?: boolean, store?: IStore<Record<string, AsyncState<T>>> }\r\n): IStore<Record<string, AsyncState<T>>> & { execute: () => Promise<void> } => {\r\n /**\r\n * Key used to store the async state in the store\r\n */\r\n const key = options?.key || 'async_data'\r\n\r\n /**\r\n * Store instance - uses existing or creates new one\r\n */\r\n const store = options?.store || createStore<Record<string, AsyncState<T>>>({\r\n namespace: `async_${key}`,\r\n silent: true\r\n })\r\n\r\n // Initial State if not present\r\n if (store.get(key) == null) {\r\n store.set(key, { data: null, loading: false, error: null, updatedAt: null })\r\n }\r\n\r\n /**\r\n * Executes the async resolver and updates store state\r\n */\r\n const run = async () => {\r\n const current = store.get(key) as AsyncState<T> | null\r\n store.set(key, {\r\n ...(current || { data: null, loading: false, error: null, updatedAt: null }),\r\n loading: true,\r\n error: null\r\n })\r\n\r\n // Wait for store to be ready if it's hydrating\r\n if ('whenReady' in store && !store.isReady) await store.whenReady()\r\n\r\n try {\r\n const result = await resolver()\r\n const prev = store.get(key) as AsyncState<T> | null\r\n store.set(key, {\r\n ...(prev || { data: null, loading: false, error: null, updatedAt: null }),\r\n data: result,\r\n loading: false,\r\n updatedAt: Date.now()\r\n }, { persist: options?.persist })\r\n } catch (e: unknown) {\r\n const prev = store.get(key) as AsyncState<T> | null\r\n store.set(key, {\r\n ...(prev || { data: null, loading: false, error: null, updatedAt: null }),\r\n error: e instanceof Error ? e : new Error(String(e)),\r\n loading: false\r\n })\r\n }\r\n }\r\n\r\n return Object.assign(store, { execute: run })\r\n}\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Immer Plugin: Adds syntactic sugar for functional updates.\r\n * Leverages the core's native Immer support.\r\n * @returns IPlugin\r\n */\r\nexport const immerPlugin = <S extends Record<string, unknown>>(): IPlugin<S> => ({\r\n name: 'gstate-immer',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n // Add sugar method to store instance using the formal registration API\r\n store._registerMethod('immer', 'setWithProduce', ((key: string, updater: (draft: unknown) => void) => {\r\n return store.set(key, updater)\r\n }) as (...args: unknown[]) => unknown)\r\n }\r\n }\r\n})\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Undo/Redo Plugin: Multi-level history management for the store.\r\n * Snapshots the entire store state for simple, robust rollbacks.\r\n * @param options Configuration for history limit\r\n * @returns IPlugin\r\n */\r\nexport const undoRedoPlugin = <S extends Record<string, unknown>>(options?: { limit?: number }): IPlugin<S> => {\r\n /** History array storing snapshots of store state */\r\n let _history: Record<string, unknown>[] = []\r\n /** Current position in the history array */\r\n let _cursor = -1\r\n /** Flag to prevent recording changes during restore operations */\r\n let _isRestoring = false\r\n\r\n /** Maximum number of history snapshots to keep */\r\n const _limit = options?.limit || 50\r\n\r\n return {\r\n name: 'gstate-undo-redo',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n // Initial Snapshot (Baseline)\r\n _history.push(store.list())\r\n _cursor = 0\r\n\r\n // Formally register methods via the core API with explicit plugin name\r\n store._registerMethod('undoRedo', 'undo', () => {\r\n if (_cursor > 0) {\r\n _isRestoring = true\r\n _cursor--\r\n const snapshot = _history[_cursor]\r\n if (!snapshot) return false\r\n\r\n // Restore snapshot using the silent internal API\r\n Object.entries(snapshot).forEach(([k, v]) => {\r\n store._setSilently(k, v)\r\n })\r\n\r\n _isRestoring = false\r\n return true\r\n }\r\n return false\r\n })\r\n\r\n store._registerMethod('undoRedo', 'redo', () => {\r\n if (_cursor < _history.length - 1) {\r\n _isRestoring = true\r\n _cursor++\r\n const snapshot = _history[_cursor]\r\n if (!snapshot) return false\r\n\r\n Object.entries(snapshot).forEach(([k, v]) => {\r\n store._setSilently(k, v)\r\n })\r\n\r\n _isRestoring = false\r\n return true\r\n }\r\n return false\r\n })\r\n\r\n store._registerMethod('undoRedo', 'canUndo', () => _cursor > 0)\r\n store._registerMethod('undoRedo', 'canRedo', () => _cursor < _history.length - 1)\r\n },\r\n\r\n onSet: ({ store }) => {\r\n if (_isRestoring) return\r\n\r\n // Wipe forward history on new manual change\r\n if (_cursor < _history.length - 1) {\r\n _history = _history.slice(0, _cursor + 1)\r\n }\r\n\r\n // Push new snapshot\r\n _history.push(store.list())\r\n\r\n if (_history.length > _limit) {\r\n _history.shift()\r\n } else {\r\n _cursor++\r\n }\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Schema Plugin: Validates state changes against a validator function.\r\n * @param schemas Map of keys to validation functions\r\n * @returns IPlugin\r\n */\r\nexport const schemaPlugin = (schemas: Record<string, (val: unknown) => boolean | string>): IPlugin => ({\r\n name: 'gstate-schema',\r\n hooks: {\r\n onSet: ({ key, value }) => {\r\n if (!key) return\r\n const validator = schemas[key]\r\n\r\n if (validator) {\r\n const result = validator(value)\r\n\r\n if (result !== true) {\r\n throw new Error(`[Schema Error] Validation failed for key \"${key}\": ${result === false ? 'Invalid type' : result}`)\r\n }\r\n }\r\n }\r\n }\r\n})\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Redux DevTools extension interface\r\n */\r\ninterface DevToolsExtension {\r\n /** Connects to the DevTools extension */\r\n connect: (options: { name: string }) => DevToolsInstance\r\n}\r\n\r\n/**\r\n * Redux DevTools instance interface\r\n */\r\ninterface DevToolsInstance {\r\n /** Initializes the DevTools with initial state */\r\n init: (state: Record<string, unknown>) => void\r\n /** Sends an action to the DevTools */\r\n send: (action: string, state: Record<string, unknown>) => void\r\n}\r\n\r\n/**\r\n * DevTools Plugin: Connects the store to Redux DevTools.\r\n * @param options Configuration for the extension\r\n * @returns IPlugin\r\n */\r\nexport const devToolsPlugin = (options?: { name?: string }): IPlugin => {\r\n const ext = globalThis as unknown\r\n const global = ext as Record<string, unknown>\r\n const extension = global.__REDUX_DEVTOOLS_EXTENSION__ as DevToolsExtension | undefined\r\n\r\n if (!extension?.connect) {\r\n return { name: 'gstate-devtools-noop', hooks: {} }\r\n }\r\n\r\n /** Reference to the DevTools instance */\r\n let _devTools: DevToolsInstance | null = null\r\n\r\n return {\r\n name: 'gstate-devtools',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n _devTools = extension.connect({ name: options?.name || 'Magnetar Store' })\r\n _devTools.init(store.list())\r\n },\r\n onSet: ({ key, store }) => {\r\n if (!key || !_devTools) return\r\n // Send full state to DevTools to enable time-travel/snapshots\r\n _devTools.send(`SET_${key.toUpperCase()}`, store.list())\r\n },\r\n onRemove: ({ key, store }) => {\r\n if (!key || !_devTools) return\r\n _devTools.send(`REMOVE_${key.toUpperCase()}`, store.list())\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Snapshot Plugin: Allows taking and restoring full store snapshots manually.\r\n * @returns IPlugin\r\n */\r\nexport const snapshotPlugin = (): IPlugin => {\r\n /** Internal storage for snapshots */\r\n const _snapshots = new Map<string, unknown>()\r\n\r\n return {\r\n name: 'gstate-snapshot',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n store._registerMethod('snapshot', 'takeSnapshot', ((name: string) => {\r\n _snapshots.set(name, store.list())\r\n }) as (...args: unknown[]) => unknown)\r\n\r\n store._registerMethod('snapshot', 'restoreSnapshot', ((name: string) => {\r\n const snap = _snapshots.get(name)\r\n if (!snap) return false\r\n\r\n store.transaction(() => {\r\n Object.entries(snap).forEach(([k, v]) => {\r\n store.set(k, v)\r\n })\r\n })\r\n return true\r\n }) as (...args: unknown[]) => unknown)\r\n\r\n store._registerMethod('snapshot', 'listSnapshots', (() => Array.from(_snapshots.keys())) as (...args: unknown[]) => unknown)\r\n store._registerMethod('snapshot', 'deleteSnapshot', ((name: string) => _snapshots.delete(name)) as (...args: unknown[]) => unknown)\r\n store._registerMethod('snapshot', 'clearSnapshots', (() => _snapshots.clear()) as (...args: unknown[]) => unknown)\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Guard Plugin: Intercepts values before they hit the store.\r\n * @param guards Map of keys to guard/transform functions\r\n * @returns IPlugin\r\n */\r\nexport const guardPlugin = (guards: Record<string, (val: unknown) => unknown>): IPlugin => ({\r\n name: 'gstate-guard',\r\n hooks: {\r\n onBeforeSet: ({ key, value, store: _store }) => {\r\n if (!key) return\r\n const guard = guards[key]\r\n\r\n if (guard) {\r\n const transformed = guard(value)\r\n\r\n // Note: Core currently doesn't support value interception for transformation\r\n // in onBeforeSet, but this serves as a placeholder for validation/logging.\r\n if (transformed !== value) {\r\n // Future: core.set could accept the transformed value\r\n }\r\n }\r\n }\r\n }\r\n})\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Analytics Plugin: Tracks state changes and sends them to a provider.\r\n * @param options Provider and filtering configuration\r\n * @returns IPlugin\r\n */\r\nexport const analyticsPlugin = (options: {\r\n provider: (event: { key: string, value: unknown, action: string }) => void,\r\n keys?: string[]\r\n}): IPlugin => ({\r\n name: 'gstate-analytics',\r\n hooks: {\r\n onSet: ({ key, value }) => {\r\n if (!key) return\r\n if (!options.keys || options.keys.includes(key)) {\r\n options.provider({ key, value, action: 'SET' })\r\n }\r\n },\r\n onRemove: ({ key }) => {\r\n if (!key) return\r\n if (!options.keys || options.keys.includes(key)) {\r\n options.provider({ key, value: null, action: 'REMOVE' })\r\n }\r\n }\r\n }\r\n})\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Sync Plugin: Synchronizes state across multiple browser tabs.\r\n * @param options Configuration for the broadcast channel\r\n * @returns IPlugin\r\n */\r\nexport const syncPlugin = (options?: { channelName?: string }): IPlugin => {\r\n /** BroadcastChannel for cross-tab communication */\r\n const _channel = new BroadcastChannel(options?.channelName || 'gstate_sync')\r\n\r\n /** Flag to prevent infinite loops when syncing from other tabs */\r\n let _isSyncing = false\r\n\r\n return {\r\n name: 'gstate-sync',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n _channel.onmessage = (event) => {\r\n const { key, value, action } = event.data\r\n if (!key) return\r\n _isSyncing = true\r\n if (action === 'REMOVE') {\r\n store.remove(key)\r\n } else {\r\n store.set(key, value)\r\n }\r\n _isSyncing = false\r\n }\r\n },\r\n onSet: ({ key, value }) => {\r\n if (!key || _isSyncing) return\r\n _channel.postMessage({ key, value, action: 'SET' })\r\n },\r\n onRemove: ({ key }) => {\r\n if (!key || _isSyncing) return\r\n _channel.postMessage({ key, action: 'REMOVE' })\r\n },\r\n onDestroy: () => {\r\n _channel.close()\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin } from '../../core/types'\r\n\r\n/**\r\n * Debug Plugin: Exposes the store to the browser console.\r\n * \u26A0\uFE0F FOR DEV/DEBUG ONLY - Never use in production!\r\n *\r\n * @example\r\n * ```typescript\r\n * if (process.env.NODE_ENV === 'development') {\r\n * store._addPlugin(debugPlugin())\r\n * }\r\n *\r\n * // In browser console:\r\n * > gstate.list()\r\n * > gstate.get('myKey')\r\n * > gstate.set('myKey', 'newValue')\r\n * ```\r\n */\r\nexport const debugPlugin = (): IPlugin => {\r\n // Security: Only run in development\r\n if (process.env.NODE_ENV === 'production') {\r\n return { name: 'gstate-debug-noop', hooks: {} }\r\n }\r\n\r\n const isDev = process.env.NODE_ENV !== 'production'\r\n\r\n const debugLog = (...args: unknown[]) => {\r\n if (isDev) console.debug(...args)\r\n }\r\n\r\n return {\r\n name: 'gstate-debug',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n // Expose store to global window object for console access\r\n if (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).gstate = {\r\n /** Get all state */\r\n list: () => {\r\n return store.list()\r\n },\r\n /** Get a specific key */\r\n get: (key: string) => {\r\n const val = store.get(key)\r\n debugLog(`[gState] get('${key}'):`, val)\r\n return val\r\n },\r\n /** Set a value */\r\n set: (key: string, value: unknown) => {\r\n const result = store.set(key, value)\r\n debugLog(`[gState] set('${key}', ${JSON.stringify(value)}):`, result)\r\n return result\r\n },\r\n /** Watch a key */\r\n watch: (key: string, callback: (val: unknown) => void) => {\r\n const unwatch = store.watch(key, callback)\r\n debugLog(`[gState] watching '${key}'`)\r\n return unwatch\r\n },\r\n /** Get store info */\r\n info: () => {\r\n const info = {\r\n namespace: store.namespace,\r\n isReady: store.isReady,\r\n keys: Object.keys(store.list()),\r\n size: Object.keys(store.list()).length\r\n }\r\n debugLog('[gState] Store Info:', info)\r\n return info\r\n },\r\n /** Clear console and show banner */\r\n banner: () => {\r\n debugLog(`\r\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\r\n\u2551 \uD83E\uDDF2 gState Debug \u2551\r\n\u2551 Type: gstate.list() \u2551\r\n\u2551 gstate.get(key) \u2551\r\n\u2551 gstate.set(key, value) \u2551\r\n\u2551 gstate.info() \u2551\r\n\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\r\n `)\r\n }\r\n }\r\n\r\n // Auto-show banner on install\r\n debugLog('[gState] Debug plugin installed. Type gstate.banner() for help.')\r\n }\r\n },\r\n onDestroy: () => {\r\n // Cleanup global reference\r\n if (typeof window !== 'undefined') {\r\n delete (window as unknown as Record<string, unknown>).gstate\r\n }\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin, PluginContext } from '../../core/types'\r\n\r\n/**\r\n * IndexedDB Plugin for RGS\r\n * Allows storing large amounts of data (GBs) by leveraging IndexedDB.\r\n * This plugin can be used as a replacement for standard localStorage persistence.\r\n */\r\n\r\nexport interface IndexedDBOptions {\r\n dbName?: string\r\n storeName?: string\r\n version?: number\r\n}\r\n\r\nexport const indexedDBPlugin = <S extends Record<string, unknown>>(options: IndexedDBOptions = {}): IPlugin<S> => {\r\n const dbName = options.dbName || 'rgs-db'\r\n const storeName = options.storeName || 'states'\r\n const dbVersion = options.version || 1\r\n let db: IDBDatabase | null = null\r\n\r\n const getDB = (): Promise<IDBDatabase> => {\r\n return new Promise((resolve, reject) => {\r\n if (db) return resolve(db)\r\n const request = indexedDB.open(dbName, dbVersion)\r\n request.onerror = () => reject(request.error)\r\n request.onsuccess = () => {\r\n db = request.result\r\n resolve(db)\r\n }\r\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\r\n const database = (event.target as IDBOpenDBRequest).result\r\n if (!database.objectStoreNames.contains(storeName)) {\r\n database.createObjectStore(storeName)\r\n }\r\n }\r\n })\r\n }\r\n\r\n const save = async (key: string, value: unknown) => {\r\n const database = await getDB()\r\n return new Promise<void>((resolve, reject) => {\r\n const tx = database.transaction(storeName, 'readwrite')\r\n const store = tx.objectStore(storeName)\r\n const request = store.put(value, key)\r\n request.onsuccess = () => resolve()\r\n request.onerror = () => reject(request.error)\r\n })\r\n }\r\n\r\n const load = async (key: string): Promise<unknown> => {\r\n const database = await getDB()\r\n return new Promise((resolve, reject) => {\r\n const tx = database.transaction(storeName, 'readonly')\r\n const store = tx.objectStore(storeName)\r\n const request = store.get(key)\r\n request.onsuccess = () => resolve(request.result)\r\n request.onerror = () => reject(request.error)\r\n })\r\n }\r\n\r\n const remove = async (key: string) => {\r\n const database = await getDB()\r\n return new Promise<void>((resolve, reject) => {\r\n const tx = database.transaction(storeName, 'readwrite')\r\n const store = tx.objectStore(storeName)\r\n const request = store.delete(key)\r\n request.onsuccess = () => resolve()\r\n request.onerror = () => reject(request.error)\r\n })\r\n }\r\n\r\n return {\r\n name: 'indexedDB',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n // Register utility methods\r\n store._registerMethod('indexedDB', 'clear', async () => {\r\n const database = await getDB()\r\n const tx = database.transaction(storeName, 'readwrite')\r\n tx.objectStore(storeName).clear()\r\n })\r\n },\r\n\r\n onInit: async ({ store }) => {\r\n // Hydrate from IndexedDB\r\n // We look for all keys that start with the store namespace\r\n const database = await getDB()\r\n const tx = database.transaction(storeName, 'readonly')\r\n const objectStore = tx.objectStore(storeName)\r\n const request = objectStore.getAllKeys()\r\n\r\n request.onsuccess = async () => {\r\n const keys = request.result as string[]\r\n const prefix = (store as import('../../core/types').IStore<S>).namespace + '_'\r\n\r\n for (const key of keys) {\r\n if (key.startsWith(prefix)) {\r\n const val = await load(key)\r\n if (val) {\r\n const storeKey = key.substring(prefix.length);\r\n // Use a silent set to avoid re-triggering persistence during hydration\r\n (store as import('../../core/types').IStore<S>)._setSilently(storeKey, (val as { d: unknown }).d)\r\n }\r\n }\r\n }\r\n }\r\n },\r\n\r\n onSet: async ({ key, value, store }) => {\r\n if (!key) return\r\n const prefix = (store as import('../../core/types').IStore<S>).namespace + '_'\r\n // We wrap the value in a structure similar to what RGS does for storage\r\n const data = {\r\n d: value,\r\n t: Date.now(),\r\n v: (store as import('../../core/types').IStore<S>)._getVersion?.(key) || 1\r\n }\r\n await save(`${prefix}${key}`, data)\r\n },\r\n\r\n onRemove: async ({ key, store }) => {\r\n if (!key) return\r\n const prefix = (store as import('../../core/types').IStore<S>).namespace + '_'\r\n await remove(`${prefix}${key}`)\r\n }\r\n }\r\n }\r\n}\r\n", "import type { IPlugin, PluginContext } from '../../core/types'\r\n\r\n/**\r\n * Sync Stats interface for reporting and analytics.\r\n */\r\nexport interface SyncStats {\r\n lastSyncTimestamp: number | null\r\n totalKeysSynced: number\r\n totalBytesSynced: number\r\n syncCount: number\r\n lastDuration: number\r\n errors: number\r\n}\r\n\r\n/**\r\n * Cloud Adapter interface.\r\n * Implement this to support different backends (MongoDB, Firebase, SQL, etc.)\r\n */\r\nexport interface CloudSyncAdapter {\r\n name: string\r\n /**\r\n * Save dirty keys to the remote database\r\n * @param data Object containing key-value pairs to sync\r\n */\r\n save: (data: Record<string, unknown>) => Promise<boolean>\r\n}\r\n\r\nexport interface CloudSyncOptions {\r\n adapter: CloudSyncAdapter\r\n autoSyncInterval?: number // ms (e.g. 60000 for 1 minute)\r\n onSync?: (stats: SyncStats) => void\r\n}\r\n\r\n/**\r\n * Cloud Sync Plugin for RGS\r\n * Allows on-demand or scheduled synchronization of local state to a remote database.\r\n * Uses internal versioning to only sync modified data (Differential Sync).\r\n */\r\nexport const cloudSyncPlugin = <S extends Record<string, unknown>>(options: CloudSyncOptions): IPlugin<S> => {\r\n const { adapter, autoSyncInterval } = options\r\n\r\n // Track last synced version for each key to perform differential sync\r\n const lastSyncedVersions = new Map<string, number>()\r\n const stats: SyncStats = {\r\n lastSyncTimestamp: null,\r\n totalKeysSynced: 0,\r\n totalBytesSynced: 0,\r\n syncCount: 0,\r\n lastDuration: 0,\r\n errors: 0\r\n }\r\n\r\n let timer: ReturnType<typeof setInterval> | null = null\r\n\r\n return {\r\n name: 'cloudSync',\r\n hooks: {\r\n onInstall: ({ store }) => {\r\n /**\r\n * Manual Sync Method\r\n * Triggers a differential sync to the cloud.\r\n */\r\n store._registerMethod('cloudSync', 'sync', async () => {\r\n const startTime = performance.now()\r\n const dirtyData: Record<string, unknown> = {}\r\n let bytesCount = 0\r\n\r\n try {\r\n const allData = store.list()\r\n const keys = Object.keys(allData)\r\n\r\n for (const key of keys) {\r\n const currentVersion = (store as import('../../core/types').IStore<S>)._getVersion?.(key) || 0\r\n const lastVersion = lastSyncedVersions.get(key) || 0\r\n\r\n if (currentVersion > lastVersion) {\r\n const val = allData[key]\r\n dirtyData[key] = val\r\n bytesCount += JSON.stringify(val).length // Rough byte estimation\r\n lastSyncedVersions.set(key, currentVersion)\r\n }\r\n }\r\n\r\n if (Object.keys(dirtyData).length === 0) return { status: 'no-change', stats }\r\n\r\n const success = await adapter.save(dirtyData)\r\n\r\n if (success) {\r\n stats.lastSyncTimestamp = Date.now()\r\n stats.totalKeysSynced += Object.keys(dirtyData).length\r\n stats.totalBytesSynced += bytesCount\r\n stats.syncCount++\r\n stats.lastDuration = performance.now() - startTime\r\n if (options.onSync) options.onSync(stats)\r\n return { status: 'success', stats }\r\n } else {\r\n throw new Error(`Adapter ${adapter.name} failed to save.`)\r\n }\r\n } catch (err) {\r\n stats.errors++\r\n console.error(`[gState] Cloud Sync Failed (${adapter.name}):`, err)\r\n return { status: 'error', error: String(err), stats }\r\n }\r\n })\r\n\r\n /**\r\n * Get Stats Method\r\n */\r\n store._registerMethod('cloudSync', 'getStats', () => stats)\r\n\r\n // Start Auto-Sync Timer if configured\r\n if (autoSyncInterval && autoSyncInterval > 0) {\r\n timer = setInterval(() => {\r\n const plugins = (store as import('../../core/types').IStore<S>).plugins\r\n const cs = plugins.cloudSync as unknown as { sync: () => Promise<unknown> }\r\n if (cs) cs.sync()\r\n }, autoSyncInterval)\r\n }\r\n },\r\n\r\n onDestroy: () => {\r\n if (timer) clearInterval(timer)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * --- CLOUD ADAPTER TEMPLATES ---\r\n */\r\n\r\n/**\r\n * Template for MongoDB (REST API / Atlas Data API)\r\n */\r\nexport const createMongoAdapter = (apiUrl: string, apiKey: string): CloudSyncAdapter => ({\r\n name: 'MongoDB-Atlas',\r\n save: async (data: Record<string, unknown>) => {\r\n const response = await fetch(`${apiUrl}/action/updateOne`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', 'api-key': apiKey },\r\n body: JSON.stringify({\r\n dataSource: 'Cluster0',\r\n database: 'rgs_cloud',\r\n collection: 'user_states',\r\n filter: { id: 'global_state' }, // Or specific user ID\r\n update: { $set: { data, updatedAt: Date.now() } },\r\n upsert: true\r\n })\r\n })\r\n return response.ok\r\n }\r\n})\r\n\r\n/**\r\n * Template for Firebase Firestore\r\n */\r\nexport const createFirestoreAdapter = (db: unknown, docPath: string): CloudSyncAdapter => ({\r\n name: 'Firebase-Firestore',\r\n save: async (data: Record<string, unknown>) => {\r\n // Assuming Firebase SDK is already initialized\r\n try {\r\n // In a real scenario, you'd use updateDoc from firebase/firestore\r\n // await updateDoc(doc(db, docPath), { ...data, updatedAt: serverTimestamp() });\r\n const isDev = process.env.NODE_ENV !== 'production'\r\n const debugLog = (...args: unknown[]) => { if (isDev) console.debug(...args) }\r\n\r\n // await updateDoc(doc(db, docPath), { ...data, updatedAt: serverTimestamp() });\r\n debugLog('[Mock] Firestore Syncing:', data)\r\n return true\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n})\r\n\r\n/**\r\n * Template for generic SQL/PostgreSQL (via standard REST API)\r\n */\r\nexport const createSqlRestAdapter = (endpoint: string, authToken: string): CloudSyncAdapter => ({\r\n name: 'SQL-REST-API',\r\n save: async (data: Record<string, unknown>) => {\r\n const response = await fetch(endpoint, {\r\n method: 'PATCH',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${authToken}`\r\n },\r\n body: JSON.stringify(data)\r\n })\r\n return response.ok\r\n }\r\n})\r\n", "/**\n * Argis (RGS) - Reactive Global State - Official Plugins\n * Performance-optimized extensions for the core engine.\n */\n\nexport { immerPlugin } from \"./official/immer.plugin\"\nexport { undoRedoPlugin } from \"./official/undo-redo.plugin\"\nexport { schemaPlugin } from \"./official/schema.plugin\"\nexport { devToolsPlugin } from \"./official/devtools.plugin\"\nexport { snapshotPlugin } from \"./official/snapshot.plugin\"\nexport { guardPlugin } from \"./official/guard.plugin\"\nexport { analyticsPlugin } from \"./official/analytics.plugin\"\nexport { syncPlugin } from \"./official/sync.plugin\"\nexport { debugPlugin } from \"./official/debug.plugin\"\nexport { indexedDBPlugin } from \"./official/indexeddb.plugin\"\nexport {\n cloudSyncPlugin,\n createMongoAdapter,\n createFirestoreAdapter,\n createSqlRestAdapter\n} from \"./official/cloud-sync.plugin\"\n\nimport type { PluginContext, IPlugin } from \"../core/types\"\n\n/**\n * Official Logger Plugin: Professional change tracking.\n * @param options Styling options for the logger\n * @returns IPlugin\n */\nexport const loggerPlugin = <S extends Record<string, unknown>>(options?: { collapsed?: boolean }): IPlugin<S> => ({\n name: 'gstate-logger',\n hooks: {\n onSet: ({ key, value, version }: PluginContext<S>) => {\n const\n time = new Date().toLocaleTimeString(),\n groupLabel = `[gState] SET: ${key} (v${version}) @ ${time}`\n\n if (options?.collapsed) console.groupCollapsed(groupLabel)\n else console.group(groupLabel)\n\n console.info('%c Value:', 'color: #4CAF50; font-weight: bold;', value)\n console.groupEnd()\n },\n onRemove: ({ key }) => {\n console.warn(`[gState] REMOVED: ${key}`)\n },\n onTransaction: ({ key }) => {\n if (key === 'START') console.group('\u2500\u2500 TRANSACTION START \u2500\u2500')\n else console.groupEnd()\n }\n }\n})\n", "/**\r\n * Argis (RGS) - Reactive Global State\r\n * Simple, secure, scalable state management for React\r\n *\r\n * @see https://github.com/dpassariello/rgs\r\n */\r\n\r\nimport { createStore as baseCreateStore } from \"./core/store\"\r\nimport { useStore as baseUseStore, getStore } from \"./core/hooks\"\r\nimport * as Security from \"./core/security\"\r\nimport type { IStore, StoreConfig } from \"./core/types\"\r\n\r\n// ============================================================================\r\n// Core API - The Magnetar Way\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a reactive store with a built-in hook.\r\n * This is the primary entry point for RGS - \"The Magnetar Way\".\r\n *\r\n * @param initialState - Initial state object\r\n * @param configOrNamespace - String for namespace (enables persistence) or full StoreConfig\r\n */\r\nexport const gstate = <S extends Record<string, unknown>>(\r\n initialState: S,\r\n configOrNamespace?: string | StoreConfig<S>\r\n) => {\r\n const config = typeof configOrNamespace === 'string'\r\n ? { namespace: configOrNamespace }\r\n : configOrNamespace\r\n\r\n // Initialize core store\r\n const store = baseCreateStore<S>(config)\r\n\r\n // Initialize state if store is empty or needs defaults\r\n if (initialState) {\r\n Object.entries(initialState).forEach(([k, v]) => {\r\n // Only set if not already hydrated/loaded from storage\r\n if (store.get(k) === null) {\r\n store._setSilently(k, v)\r\n }\r\n })\r\n }\r\n\r\n // Magic function that returns a typed hook when called with a key\r\n const magic = <K extends keyof S>(key: K) => baseUseStore<S[K], S>(key as string, store)\r\n\r\n // Expose as global for debugging purposes in dev environments\r\n if (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).gState = store;\r\n (window as unknown as Record<string, unknown>).rgs = store\r\n }\r\n\r\n return Object.assign(magic, store) as IStore<S> & (<K extends keyof S>(key: K) => readonly [S[K] | undefined, (val: S[K] | ((draft: S[K]) => S[K]), options?: unknown) => boolean])\r\n}\r\n\r\nexport { baseCreateStore as createStore }\r\n\r\nexport {\r\n useStore,\r\n useIsStoreReady,\r\n initState,\r\n getStore,\r\n destroyState,\r\n useStore as useGState,\r\n useStore as useSimpleState\r\n} from \"./core/hooks\"\r\n\r\nexport { createAsyncStore } from \"./core/async\"\r\n\r\n// ============================================================================\r\n// Local-First Sync Engine\r\n// ============================================================================\r\n\r\nexport { SyncEngine, createSyncEngine } from \"./core/sync\"\r\nexport type {\r\n SyncConfig,\r\n SyncState,\r\n SyncResult,\r\n SyncStrategy,\r\n ConflictInfo,\r\n ConflictResolution\r\n} from \"./core/sync\"\r\n\r\nexport { initSync, destroySync, useSyncedState, useSyncStatus, triggerSync } from \"./core/hooks\"\r\n\r\n// ============================================================================\r\n// Plugins\r\n// ============================================================================\r\n\r\nexport * from \"./plugins/index\"\r\n\r\n// ============================================================================\r\n// Security & Compliance (Unified)\r\n// ============================================================================\r\n\r\n// Stateless Utilities\r\nexport {\r\n generateEncryptionKey,\r\n exportKey,\r\n importKey,\r\n isCryptoAvailable,\r\n setAuditLogger,\r\n logAudit,\r\n validateKey,\r\n sanitizeValue\r\n} from \"./core/security\"\r\n\r\n// Store-aware Wrappers for Global Convenience\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const addAccessRule = (pattern: string | ((key: string, userId?: string) => boolean), perms: Security.Permission[]) => getStore()?.addAccessRule(pattern, perms)\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const hasPermission = (key: string, action: Security.Permission, uid?: string) => getStore()?.hasPermission(key, action, uid) ?? true\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const recordConsent = (uid: string, p: string, g: boolean) => {\r\n const s = getStore()\r\n if (!s) throw new Error('[gState] recordConsent failed: No store found. call initState() first.')\r\n return s.recordConsent(uid, p, g)\r\n}\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const hasConsent = (uid: string, p: string) => getStore()?.hasConsent(uid, p) ?? false\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const getConsents = (uid: string) => getStore()?.getConsents(uid) ?? []\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const revokeConsent = (uid: string, p: string) => getStore()?.revokeConsent(uid, p)\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const exportUserData = (uid: string) => {\r\n const s = getStore()\r\n if (!s) throw new Error('[gState] exportUserData failed: No store found.')\r\n return s.exportUserData(uid)\r\n}\r\n/** @deprecated Use store instance methods for better isolation in multi-store scenarios */\r\nexport const deleteUserData = (uid: string) => {\r\n const s = getStore()\r\n if (!s) throw new Error('[gState] deleteUserData failed: No store found.')\r\n return s.deleteUserData(uid)\r\n}\r\n\r\n// Legacy cleanup helpers (now handled by destroyState / destroy())\r\n/** @deprecated Logic now tied to store lifecycle. Use destroyState() or store.destroy() */\r\nexport const clearAccessRules = () => { /* No-op globally */ }\r\n/** @deprecated Logic now tied to store lifecycle. Use destroyState() or store.destroy() */\r\nexport const clearAllConsents = () => { /* No-op globally */ }\r\n\r\nexport type { EncryptionKey, AuditEntry, Permission, AccessRule, ConsentRecord } from \"./core/security\"\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\nexport type {\r\n IStore,\r\n StoreConfig,\r\n PersistOptions,\r\n StateUpdater,\r\n ComputedSelector,\r\n WatcherCallback\r\n} from \"./core/types\"\r\n\r\n// ============================================================================\r\n// Global Augmentation\r\n// ============================================================================\r\n\r\n/* eslint-disable no-var */\r\ndeclare global {\r\n var createStore: typeof baseCreateStore\r\n var gstate: <S extends Record<string, unknown>>(initialState: S, configOrNamespace?: string | StoreConfig<S>) => IStore<S> & ((key: string) => unknown)\r\n var initState: typeof import(\"./core/hooks\").initState\r\n var destroyState: typeof import(\"./core/hooks\").destroyState\r\n var gState: IStore<Record<string, unknown>>\r\n var rgs: IStore<Record<string, unknown>>\r\n var useStore: typeof baseUseStore\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["_immerProduce", "_immerFreeze", "isCryptoAvailable", "generateEncryptionKey", "key", "iv", "exportKey", "encryptionKey", "exportedKey", "importKey", "keyData", "ivData", "keyBytes", "c", "ivBytes", "encrypt", "data", "encoder", "encoded", "encrypted", "combined", "decrypt", "encryptedData", "ciphertext", "decrypted", "_auditLogger", "setAuditLogger", "logger", "isAuditActive", "logAudit", "entry", "addAccessRule", "rules", "pattern", "perms", "hasPermission", "action", "_userId", "matches", "sanitizeValue", "value", "decoded", "match", "hexMatch", "decMatch", "sanitized", "k", "v", "validateKey", "recordConsent", "consents", "userId", "purpose", "granted", "record", "user", "hasConsent", "userConsents", "i", "revokeConsent", "getConsents", "exportUserData", "deleteUserData", "count", "deepClone", "obj", "seen", "clone", "value", "result", "v", "k", "keys", "key", "isEqual", "a", "b", "i", "keysA", "keysB", "_immerFreeze", "_getPrefix", "namespace", "flushDisk", "ctx", "store", "config", "diskQueue", "storage", "encryptionKey", "audit", "onError", "silent", "currentVersion", "prefix", "stateObj", "v", "dataValue", "isEncoded", "e", "error", "queue", "key", "data", "encrypt", "hydrateStore", "calculateSize", "emit", "sizes", "versions", "immer", "persisted", "savedV", "i", "k", "raw", "meta", "d", "decrypt", "err", "final", "frozen", "deepClone", "size", "oldSize", "runHook", "ctx", "name", "hookContext", "p", "hook", "e", "error", "installPlugin", "plugin", "storeInstance", "SyncEngine", "store", "config", "online", "cb", "state", "key", "value", "version", "deepClone", "startTime", "syncedKeys", "conflicts", "errors", "pendingChanges", "p", "change", "remoteVersion", "conflict", "resolution", "err", "result", "errorMsg", "keys", "response", "data", "retries", "localChange", "callback", "createSyncEngine", "StorageAdapters", "_m", "k", "v", "i", "createStore", "config", "_store", "_versions", "_sizes", "_listeners", "_keyListeners", "_middlewares", "_watchers", "_computed", "_computedDeps", "_plugins", "_diskQueue", "_regexCache", "_accessRules", "_consents", "_namespace", "_silent", "_debounceTime", "_currentVersion", "_storage", "_onError", "_maxObjectSize", "_maxTotalSize", "_encryptionKey", "_validateInput", "_auditEnabled", "_userId", "_immer", "_persistByDefault", "rule", "addAccessRule", "_isTransaction", "_pendingEmit", "_isReady", "_totalSize", "_diskTimer", "_snapshot", "_readyResolver", "_readyPromise", "resolve", "_getPrefix", "getPersistenceContext", "_audit", "getPluginContext", "_calculateSize", "val", "type", "bytes", "stack", "seen", "value", "obj", "key", "_runHook", "name", "context", "runHook", "action", "success", "error", "isAuditActive", "logAudit", "_updateComputed", "comp", "depsFound", "getter", "instance", "newValue", "d", "dependents", "isEqual", "_immerFreeze", "deepClone", "_emit", "changedKey", "dependentKey", "watchers", "w", "e", "keyListeners", "l", "_flushDisk", "flushDisk", "_methodNamespace", "oldSize", "frozen", "newSize", "pluginName", "methodName", "fn", "isUnsafeKey", "valOrUp", "options", "oldVal", "newVal", "_immerProduce", "validateKey", "hasPermission", "sani", "sanitizeValue", "finalSize", "est", "shouldPersist", "selector", "callback", "set", "old", "deleted", "prefix", "m", "_unloadHandler", "p", "installPlugin", "cb", "pattern", "permissions", "userId", "perms", "matches", "re", "purpose", "granted", "recordConsent", "hasConsent", "getConsents", "revokeConsent", "exportUserData", "deleteUserData", "hydrateStore", "_syncEngine", "SyncEngine", "useSyncExternalStore", "useDebugValue", "useMemo", "useCallback", "useEffect", "useState", "_defaultStore", "initState", "config", "store", "createStore", "destroyState", "useIsStoreReady", "targetStore", "subscribe", "useMemo", "callback", "useSyncExternalStore", "getStore", "useStore", "keyOrSelector", "store", "targetStore", "useMemo", "_defaultStore", "ghostStore", "noop", "noopFalse", "noopNull", "safeStore", "isSelector", "key", "selector", "subscribe", "useCallback", "callback", "getSnapshot", "getServerSnapshot", "value", "useSyncExternalStore", "setter", "val", "options", "useDebugValue", "v", "_syncEngines", "initSync", "config", "engine", "SyncEngine", "destroySync", "namespace", "useSyncedState", "result", "syncState", "setSyncState", "useState", "useEffect", "syncedSetter", "currentValue", "useSyncStatus", "state", "setState", "updateState", "isOnline", "isSyncing", "pendingChanges", "conflicts", "s", "unsubscribes", "fn", "triggerSync", "targetNamespace", "createAsyncStore", "resolver", "options", "key", "store", "createStore", "current", "result", "prev", "e", "immerPlugin", "store", "key", "updater", "undoRedoPlugin", "options", "_history", "_cursor", "_isRestoring", "_limit", "store", "snapshot", "k", "v", "schemaPlugin", "schemas", "key", "value", "validator", "result", "devToolsPlugin", "options", "extension", "_devTools", "store", "key", "snapshotPlugin", "_snapshots", "store", "name", "snap", "k", "v", "guardPlugin", "guards", "key", "value", "_store", "guard", "transformed", "analyticsPlugin", "options", "key", "value", "syncPlugin", "options", "_channel", "_isSyncing", "store", "event", "key", "value", "action", "debugPlugin", "indexedDBPlugin", "options", "dbName", "storeName", "dbVersion", "db", "getDB", "resolve", "reject", "request", "event", "database", "save", "key", "value", "load", "remove", "store", "keys", "prefix", "val", "storeKey", "data", "cloudSyncPlugin", "options", "adapter", "autoSyncInterval", "lastSyncedVersions", "stats", "timer", "store", "startTime", "dirtyData", "bytesCount", "allData", "keys", "key", "currentVersion", "lastVersion", "val", "err", "cs", "createMongoAdapter", "apiUrl", "apiKey", "data", "createFirestoreAdapter", "db", "docPath", "args", "createSqlRestAdapter", "endpoint", "authToken", "loggerPlugin", "options", "key", "value", "version", "time", "groupLabel", "gstate", "initialState", "configOrNamespace", "store", "createStore", "k", "v", "magic", "key", "useStore", "addAccessRule", "pattern", "perms", "getStore", "hasPermission", "key", "action", "uid", "recordConsent", "p", "g", "s", "hasConsent", "getConsents", "revokeConsent", "exportUserData", "deleteUserData", "clearAccessRules", "clearAllConsents"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@biglogic/rgs",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.3",
|
|
4
4
|
"description": "Argis (RGS) - Reactive Global State: A react state everywhere made easy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -49,9 +49,6 @@
|
|
|
49
49
|
"npm:pack": "npm run build && cd dist && npm pack",
|
|
50
50
|
"npm:publish": "npm run build && npm run build:extension && cd dist && npm publish --access=public"
|
|
51
51
|
},
|
|
52
|
-
"dependencies": {
|
|
53
|
-
"immer": "^11.1.4"
|
|
54
|
-
},
|
|
55
52
|
"peerDependencies": {
|
|
56
53
|
"react": ">=16.8.0",
|
|
57
54
|
"react-dom": ">=16.8.0"
|
|
@@ -64,14 +61,21 @@
|
|
|
64
61
|
"optional": false
|
|
65
62
|
}
|
|
66
63
|
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"immer": "^11.1.4"
|
|
66
|
+
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
+
"memorio": "^2.2.1",
|
|
68
69
|
"@types/jest": "30.0.0",
|
|
69
70
|
"@types/node": "^25.3.0",
|
|
70
71
|
"@types/react": "^19.2.14",
|
|
71
72
|
"@types/react-dom": "^19.2.3",
|
|
72
|
-
"
|
|
73
|
-
"esbuild": "
|
|
74
|
-
"esbuild-plugin-
|
|
73
|
+
"esbuild": "0.27.3",
|
|
74
|
+
"esbuild-node-externals": "1.20.1",
|
|
75
|
+
"esbuild-plugin-alias": "0.2.1",
|
|
76
|
+
"esbuild-plugin-copy": "2.1.1",
|
|
77
|
+
"esbuild-sass-plugin": "3.6.0",
|
|
78
|
+
"esbuild-scss-modules-plugin": "1.1.1",
|
|
75
79
|
"react": "^19.2.4",
|
|
76
80
|
"react-dom": "^19.2.4",
|
|
77
81
|
"ts-jest": "29.4.6",
|
package/rgs-extension.vsix
CHANGED
|
Binary file
|
package/advanced.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var jt=Object.defineProperty;var $t=(e,t)=>{for(var r in t)jt(e,r,{get:t[r],enumerable:!0})};var wt=Symbol.for("immer-nothing"),ft=Symbol.for("immer-draftable"),M=Symbol.for("immer-state");function I(e,...t){throw new Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var k=Object,G=k.getPrototypeOf,pe="constructor",Se="prototype",Ue="configurable",ge="enumerable",fe="writable",Y="value",j=e=>!!e&&!!e[M];function N(e){return e?bt(e)||be(e)||!!e[ft]||!!e[pe]?.[ft]||Ee(e)||Ce(e):!1}var Lt=k[Se][pe].toString(),dt=new WeakMap;function bt(e){if(!e||!Ke(e))return!1;let t=G(e);if(t===null||t===k[Se])return!0;let r=k.hasOwnProperty.call(t,pe)&&t[pe];if(r===Object)return!0;if(!H(r))return!1;let n=dt.get(r);return n===void 0&&(n=Function.toString.call(r),dt.set(r,n)),n===Lt}function we(e,t,r=!0){te(e)===0?(r?Reflect.ownKeys(e):k.keys(e)).forEach(s=>{t(s,e[s],e)}):e.forEach((n,s)=>t(s,n,e))}function te(e){let t=e[M];return t?t.type_:be(e)?1:Ee(e)?2:Ce(e)?3:0}var pt=(e,t,r=te(e))=>r===2?e.has(t):k[Se].hasOwnProperty.call(e,t),je=(e,t,r=te(e))=>r===2?e.get(t):e[t],_e=(e,t,r,n=te(e))=>{n===2?e.set(t,r):n===3?e.add(r):e[t]=r};function Wt(e,t){return e===t?e!==0||1/e===1/t:e!==e&&t!==t}var be=Array.isArray,Ee=e=>e instanceof Map,Ce=e=>e instanceof Set,Ke=e=>typeof e=="object",H=e=>typeof e=="function",Ne=e=>typeof e=="boolean";function Bt(e){let t=+e;return Number.isInteger(t)&&String(t)===e}var V=e=>e.copy_||e.base_;var Je=e=>e.modified_?e.copy_:e.base_;function $e(e,t){if(Ee(e))return new Map(e);if(Ce(e))return new Set(e);if(be(e))return Array[Se].slice.call(e);let r=bt(e);if(t===!0||t==="class_only"&&!r){let n=k.getOwnPropertyDescriptors(e);delete n[M];let s=Reflect.ownKeys(n);for(let i=0;i<s.length;i++){let c=s[i],l=n[c];l[fe]===!1&&(l[fe]=!0,l[Ue]=!0),(l.get||l.set)&&(n[c]={[Ue]:!0,[fe]:!0,[ge]:l[ge],[Y]:e[c]})}return k.create(G(e),n)}else{let n=G(e);if(n!==null&&r)return{...e};let s=k.create(n);return k.assign(s,e)}}function F(e,t=!1){return Pe(e)||j(e)||!N(e)||(te(e)>1&&k.defineProperties(e,{set:le,add:le,clear:le,delete:le}),k.freeze(e),t&&we(e,(r,n)=>{F(n,!0)},!1)),e}function Ht(){I(2)}var le={[Y]:Ht};function Pe(e){return e===null||!Ke(e)?!0:k.isFrozen(e)}var he="MapSet",Le="Patches",gt="ArrayMethods",Et={};function W(e){let t=Et[e];return t||I(0,e),t}var _t=e=>!!Et[e];var Z,Ct=()=>Z,Gt=(e,t)=>({drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0,handledSet_:new Set,processedForPatches_:new Set,mapSetPlugin_:_t(he)?W(he):void 0,arrayMethodsPlugin_:_t(gt)?W(gt):void 0});function ht(e,t){t&&(e.patchPlugin_=W(Le),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function We(e){Be(e),e.drafts_.forEach(Kt),e.drafts_=null}function Be(e){e===Z&&(Z=e.parent_)}var yt=e=>Z=Gt(Z,e);function Kt(e){let t=e[M];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function mt(e,t){t.unfinalizedDrafts_=t.drafts_.length;let r=t.drafts_[0];if(e!==void 0&&e!==r){r[M].modified_&&(We(t),I(4)),N(e)&&(e=St(t,e));let{patchPlugin_:s}=t;s&&s.generateReplacementPatches_(r[M].base_,e,t)}else e=St(t,r);return Jt(t,e,!0),We(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e!==wt?e:void 0}function St(e,t){if(Pe(t))return t;let r=t[M];if(!r)return ye(t,e.handledSet_,e);if(!ve(r,e))return t;if(!r.modified_)return r.base_;if(!r.finalized_){let{callbacks_:n}=r;if(n)for(;n.length>0;)n.pop()(e);Mt(r,e)}return r.copy_}function Jt(e,t,r=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&F(t,r)}function Pt(e){e.finalized_=!0,e.scope_.unfinalizedDrafts_--}var ve=(e,t)=>e.scope_===t,Qt=[];function vt(e,t,r,n){let s=V(e),i=e.type_;if(n!==void 0&&je(s,n,i)===t){_e(s,n,r,i);return}if(!e.draftLocations_){let l=e.draftLocations_=new Map;we(s,(_,y)=>{if(j(y)){let x=l.get(y)||[];x.push(_),l.set(y,x)}})}let c=e.draftLocations_.get(t)??Qt;for(let l of c)_e(s,l,r,i)}function qt(e,t,r){e.callbacks_.push(function(s){let i=t;if(!i||!ve(i,s))return;s.mapSetPlugin_?.fixSetContents(i);let c=Je(i);vt(e,i.draft_??i,c,r),Mt(i,s)})}function Mt(e,t){if(e.modified_&&!e.finalized_&&(e.type_===3||e.type_===1&&e.allIndicesReassigned_||(e.assigned_?.size??0)>0)){let{patchPlugin_:n}=t;if(n){let s=n.getPath(e);s&&n.generatePatches_(e,s,t)}Pt(e)}}function Xt(e,t,r){let{scope_:n}=e;if(j(r)){let s=r[M];ve(s,n)&&s.callbacks_.push(function(){de(e);let c=Je(s);vt(e,r,c,t)})}else N(r)&&e.callbacks_.push(function(){let i=V(e);e.type_===3?i.has(r)&&ye(r,n.handledSet_,n):je(i,t,e.type_)===r&&n.drafts_.length>1&&(e.assigned_.get(t)??!1)===!0&&e.copy_&&ye(je(e.copy_,t,e.type_),n.handledSet_,n)})}function ye(e,t,r){return!r.immer_.autoFreeze_&&r.unfinalizedDrafts_<1||j(e)||t.has(e)||!N(e)||Pe(e)||(t.add(e),we(e,(n,s)=>{if(j(s)){let i=s[M];if(ve(i,r)){let c=Je(i);_e(e,n,c,e.type_),Pt(i)}}else N(s)&&ye(s,t,r)})),e}function Yt(e,t){let r=be(e),n={type_:r?1:0,scope_:t?t.scope_:Ct(),modified_:!1,finalized_:!1,assigned_:void 0,parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1,callbacks_:void 0},s=n,i=me;r&&(s=[n],i=ee);let{revoke:c,proxy:l}=Proxy.revocable(s,i);return n.draft_=l,n.revoke_=c,[l,n]}var me={get(e,t){if(t===M)return e;let r=e.scope_.arrayMethodsPlugin_,n=e.type_===1&&typeof t=="string";if(n&&r?.isArrayOperationMethod(t))return r.createMethodInterceptor(e,t);let s=V(e);if(!pt(s,t,e.type_))return Zt(e,s,t);let i=s[t];if(e.finalized_||!N(i)||n&&e.operationMethod&&r?.isMutatingArrayMethod(e.operationMethod)&&Bt(t))return i;if(i===Fe(e.base_,t)){de(e);let c=e.type_===1?+t:t,l=Ge(e.scope_,i,e,c);return e.copy_[c]=l}return i},has(e,t){return t in V(e)},ownKeys(e){return Reflect.ownKeys(V(e))},set(e,t,r){let n=xt(V(e),t);if(n?.set)return n.set.call(e.draft_,r),!0;if(!e.modified_){let s=Fe(V(e),t),i=s?.[M];if(i&&i.base_===r)return e.copy_[t]=r,e.assigned_.set(t,!1),!0;if(Wt(r,s)&&(r!==void 0||pt(e.base_,t,e.type_)))return!0;de(e),He(e)}return e.copy_[t]===r&&(r!==void 0||t in e.copy_)||Number.isNaN(r)&&Number.isNaN(e.copy_[t])||(e.copy_[t]=r,e.assigned_.set(t,!0),Xt(e,t,r)),!0},deleteProperty(e,t){return de(e),Fe(e.base_,t)!==void 0||t in e.base_?(e.assigned_.set(t,!1),He(e)):e.assigned_.delete(t),e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){let r=V(e),n=Reflect.getOwnPropertyDescriptor(r,t);return n&&{[fe]:!0,[Ue]:e.type_!==1||t!=="length",[ge]:n[ge],[Y]:r[t]}},defineProperty(){I(11)},getPrototypeOf(e){return G(e.base_)},setPrototypeOf(){I(12)}},ee={};for(let e in me){let t=me[e];ee[e]=function(){let r=arguments;return r[0]=r[0][0],t.apply(this,r)}}ee.deleteProperty=function(e,t){return ee.set.call(this,e,t,void 0)};ee.set=function(e,t,r){return me.set.call(this,e[0],t,r,e[0])};function Fe(e,t){let r=e[M];return(r?V(r):e)[t]}function Zt(e,t,r){let n=xt(t,r);return n?Y in n?n[Y]:n.get?.call(e.draft_):void 0}function xt(e,t){if(!(t in e))return;let r=G(e);for(;r;){let n=Object.getOwnPropertyDescriptor(r,t);if(n)return n;r=G(r)}}function He(e){e.modified_||(e.modified_=!0,e.parent_&&He(e.parent_))}function de(e){e.copy_||(e.assigned_=new Map,e.copy_=$e(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var er=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!1,this.produce=(t,r,n)=>{if(H(t)&&!H(r)){let i=r;r=t;let c=this;return function(_=i,...y){return c.produce(_,x=>r.call(this,x,...y))}}H(r)||I(6),n!==void 0&&!H(n)&&I(7);let s;if(N(t)){let i=yt(this),c=Ge(i,t,void 0),l=!0;try{s=r(c),l=!1}finally{l?We(i):Be(i)}return ht(i,n),mt(s,i)}else if(!t||!Ke(t)){if(s=r(t),s===void 0&&(s=t),s===wt&&(s=void 0),this.autoFreeze_&&F(s,!0),n){let i=[],c=[];W(Le).generateReplacementPatches_(t,s,{patches_:i,inversePatches_:c}),n(i,c)}return s}else I(1,t)},this.produceWithPatches=(t,r)=>{if(H(t))return(c,...l)=>this.produceWithPatches(c,_=>t(_,...l));let n,s;return[this.produce(t,r,(c,l)=>{n=c,s=l}),n,s]},Ne(e?.autoFreeze)&&this.setAutoFreeze(e.autoFreeze),Ne(e?.useStrictShallowCopy)&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),Ne(e?.useStrictIteration)&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){N(e)||I(8),j(e)&&(e=tr(e));let t=yt(this),r=Ge(t,e,void 0);return r[M].isManual_=!0,Be(t),r}finishDraft(e,t){let r=e&&e[M];(!r||!r.isManual_)&&I(9);let{scope_:n}=r;return ht(n,t),mt(void 0,n)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let r;for(r=t.length-1;r>=0;r--){let s=t[r];if(s.path.length===0&&s.op==="replace"){e=s.value;break}}r>-1&&(t=t.slice(r+1));let n=W(Le).applyPatches_;return j(e)?n(e,t):this.produce(e,s=>n(s,t))}};function Ge(e,t,r,n){let[s,i]=Ee(t)?W(he).proxyMap_(t,r):Ce(t)?W(he).proxySet_(t,r):Yt(t,r);return(r?.scope_??Ct()).drafts_.push(s),i.callbacks_=r?.callbacks_??[],i.key_=n,r&&n!==void 0?qt(r,i,n):i.callbacks_.push(function(_){_.mapSetPlugin_?.fixSetContents(i);let{patchPlugin_:y}=_;i.modified_&&y&&y.generatePatches_(i,[],_)}),s}function tr(e){return j(e)||I(10,e),At(e)}function At(e){if(!N(e)||Pe(e))return e;let t=e[M],r,n=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,r=$e(e,t.scope_.immer_.useStrictShallowCopy_),n=t.scope_.immer_.shouldUseStrictIteration()}else r=$e(e,!0);return we(r,(s,i)=>{_e(r,s,At(i))},n),t&&(t.finalized_=!1),r}var rr=new er,kt=rr.produce;var ke={};$t(ke,{addAccessRule:()=>xe,decrypt:()=>qe,deleteUserData:()=>nt,encrypt:()=>Qe,exportKey:()=>or,exportUserData:()=>rt,generateEncryptionKey:()=>nr,getConsents:()=>tt,hasConsent:()=>Ze,hasPermission:()=>oe,importKey:()=>sr,isAuditActive:()=>Xe,isCryptoAvailable:()=>Ot,logAudit:()=>ne,recordConsent:()=>Ae,revokeConsent:()=>et,sanitizeValue:()=>re,setAuditLogger:()=>ir,validateKey:()=>Ye});var Ot=typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof crypto.subtle.generateKey=="function",nr=async()=>{if(!Ot)throw new Error("Web Crypto API not available");let e=await crypto.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),t=crypto.getRandomValues(new Uint8Array(12));return{key:e,iv:t}},or=async e=>{let t=await crypto.subtle.exportKey("raw",e.key);return{key:btoa(String.fromCharCode(...new Uint8Array(t))),iv:btoa(String.fromCharCode(...e.iv))}},sr=async(e,t)=>{let r=Uint8Array.from(atob(e),i=>i.charCodeAt(0)),n=Uint8Array.from(atob(t),i=>i.charCodeAt(0));return{key:await crypto.subtle.importKey("raw",r,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),iv:n}},Qe=async(e,t)=>{let r=new TextEncoder,n=r.encode(JSON.stringify(e)),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:t.iv},t.key,n),i=new Uint8Array(t.iv.length+s.byteLength);return i.set(t.iv),i.set(new Uint8Array(s),t.iv.length),btoa(String.fromCharCode(...i))},qe=async(e,t)=>{let r=Uint8Array.from(atob(e),c=>c.charCodeAt(0)),n=r.slice(0,12),s=r.slice(12),i=await crypto.subtle.decrypt({name:"AES-GCM",iv:n},t.key,s);return JSON.parse(new TextDecoder().decode(i))},Me=null,ir=e=>{Me=e},Xe=()=>Me!==null,ne=e=>{Me&&Me(e)},xe=(e,t,r)=>{e.set(t instanceof RegExp?t.source:t,r)},oe=(e,t,r,n)=>{if(e.size===0)return!0;for(let[s,i]of e){let c;if(typeof s=="function")c=s(t,n);else try{c=new RegExp(s).test(t)}catch{continue}if(c)return i.includes(r)||i.includes("admin")}return!1},re=e=>{if(typeof e=="string"){let t=e.replace(/&#[xX]?[0-9a-fA-F]+;?/g,n=>{let s=n.match(/&#x([0-9a-fA-F]+);?/i);if(s&&s[1])return String.fromCharCode(parseInt(s[1],16));let i=n.match(/&#([0-9]+);?/);return i&&i[1]?String.fromCharCode(parseInt(i[1],10)):""});try{t=decodeURIComponent(t)}catch{}return t.replace(/\b(javascript|vbscript|data:text\/html|about:blank|chrome:)/gi,"[SEC-REMOVED]").replace(/<script\b[^>]*>[\s\S]*?<\s*\/\s*script\b[^>]*>/gi,"[SEC-REMOVED]").replace(/on\w+\s*=/gi,"[SEC-REMOVED]=").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,"[SEC-REMOVED]").replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi,"[SEC-REMOVED]").replace(/<embed\b[^<]*(?:(?!<\/embed>)<[^<]*)*<\/embed>/gi,"[SEC-REMOVED]").replace(/<svg\b[^<]*(?:(?!<\/svg>)<[^<]*)*<\/svg>/gi,"[SEC-REMOVED]").replace(/<form\b[^<]*(?:(?!<\/form>)<[^<]*)*<\/form>/gi,"[SEC-REMOVED]").replace(/<base\b[^<]*(?:(?!<\/base>)<[^<]*)*<\/base>/gi,"[SEC-REMOVED]").replace(/<link\b[^<]*(?:(?!<\/link>)<[^<]*)*<\/link>/gi,"[SEC-REMOVED]").replace(/<meta\b[^<]*(?:(?!<\/meta>)<[^<]*)*<\/meta>/gi,"[SEC-REMOVED]").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,"[SEC-REMOVED]")}if(e&&typeof e=="object"&&!Array.isArray(e)){if(Object.getPrototypeOf(e)===Object.prototype){let t={};for(let[r,n]of Object.entries(e))t[r]=re(n);return t}return e}return Array.isArray(e)?e.map(t=>re(t)):e},Ye=e=>/^[a-zA-Z0-9_.-]+$/.test(e)&&e.length<=256,Ae=(e,t,r,n)=>{let s={id:crypto.randomUUID(),purpose:r,granted:n,timestamp:Date.now()},i=e.get(t)||[];return i.push(s),e.set(t,i),ne({timestamp:Date.now(),action:"set",key:`consent:${r}`,userId:t,success:!0}),s},Ze=(e,t,r)=>{let n=e.get(t);if(!n)return!1;for(let s=n.length-1;s>=0;s--){let i=n[s];if(i&&i.purpose===r)return i.granted}return!1},et=(e,t,r)=>Ae(e,t,r,!1),tt=(e,t)=>e.get(t)||[],rt=(e,t)=>({userId:t,exportedAt:Date.now(),consents:e.get(t)||[]}),nt=(e,t)=>{let r=e.get(t)?.length||0;return e.delete(t),{success:!0,deletedConsents:r}};var K=e=>{if(e===null||typeof e!="object")return e;if(typeof structuredClone=="function")try{return structuredClone(e)}catch{}let t=new WeakMap,r=n=>{if(n===null||typeof n!="object"||typeof n=="function")return n;if(t.has(n))return t.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof Map){let c=new Map;return t.set(n,c),n.forEach((l,_)=>c.set(r(_),r(l))),c}if(n instanceof Set){let c=new Set;return t.set(n,c),n.forEach(l=>c.add(r(l))),c}let s=Array.isArray(n)?[]:Object.create(Object.getPrototypeOf(n));t.set(n,s);let i=[...Object.keys(n),...Object.getOwnPropertySymbols(n)];for(let c of i)s[c]=r(n[c]);return s};return r(e)},se=(e,t)=>{if(e===t)return!0;if(e===null||t===null||typeof e!="object"||typeof t!="object")return e===t;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let s=0;s<e.length;s++)if(!se(e[s],t[s]))return!1;return!0}let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let s=0;s<r.length;s++){let i=r[s];if(!(i in t)||!se(e[i],t[i]))return!1}return!0};var Rt=e=>`${e}_`,Dt=async e=>{if(!e.storage)return;let{store:t,config:r,diskQueue:n,storage:s,encryptionKey:i,audit:c,onError:l,silent:_,currentVersion:y}=e,x=Rt(r.namespace||"gstate");try{let C={};t.forEach((P,b)=>{C[b]=P});let p,S=r?.encoded;S?p=btoa(JSON.stringify(C)):p=JSON.stringify(C),s.setItem(x.replace("_",""),JSON.stringify({v:1,t:Date.now(),e:null,d:p,_sys_v:y,_b64:S?!0:void 0})),c("set","FULL_STATE",!0)}catch(C){let p=C instanceof Error?C:new Error(String(C));l?l(p,{operation:"persist",key:"FULL_STATE"}):_||console.error("[gState] Persist failed: ",p)}let z=Array.from(n.entries());n.clear();for(let[C,p]of z)try{let S=p.value,P=p.options.encoded||p.options.secure;if(p.options.encrypted){if(!i)throw new Error(`Encryption key missing for "${C}"`);S=await Qe(p.value,i)}else P?S=btoa(JSON.stringify(p.value)):typeof p.value=="object"&&p.value!==null&&(S=JSON.stringify(p.value));s.setItem(`${x}${C}`,JSON.stringify({v:e.versions.get(C)||1,t:Date.now(),e:p.options.ttl?Date.now()+p.options.ttl:null,d:S,_sys_v:y,_enc:p.options.encrypted?!0:void 0,_b64:P?!0:void 0})),c("set",C,!0)}catch(S){let P=S instanceof Error?S:new Error(String(S));l?l(P,{operation:"persist",key:C}):_||console.error("[gState] Persist failed: ",P)}},It=async(e,t,r)=>{let{storage:n,config:s,encryptionKey:i,audit:c,onError:l,silent:_,currentVersion:y,store:x,sizes:z,versions:C}=e,p=Rt(s.namespace||"gstate"),S=s.immer??!0;if(n)try{let P={},b=0;for(let D=0;D<(n.length||0);D++){let m=n.key(D);if(!m||!m.startsWith(p))continue;let E=n.getItem(m);if(E)try{let h=JSON.parse(E),A=m.substring(p.length);if(b=Math.max(b,h._sys_v!==void 0?h._sys_v:h.v||0),h.e&&Date.now()>h.e){n.removeItem(m),D--;continue}let O=h.d;if(h._enc&&i)O=await qe(O,i);else if(typeof O=="string"){if(h._b64)try{O=JSON.parse(atob(O))}catch{}else if(O.startsWith("{")||O.startsWith("["))try{O=JSON.parse(O)}catch{}}P[A]=O,c("hydrate",A,!0)}catch(h){c("hydrate",m,!1,String(h));let A=h instanceof Error?h:new Error(String(h));l?l(A,{operation:"hydration",key:m}):_||console.error(`[gState] Hydration failed for "${m}": `,h)}}let ie=b<y&&s.migrate?s.migrate(P,b):P;Object.entries(ie).forEach(([D,m])=>{let E=S&&m!==null&&typeof m=="object"?F(K(m),!0):m,h=t(E),A=z.get(D)||0;e.totalSize=e.totalSize-A+h,z.set(D,h),x.set(D,E),C.set(D,1)}),r()}catch(P){let b=P instanceof Error?P:new Error(String(P));l?l(b,{operation:"hydration"}):_||console.error("[gState] Hydration failed: ",b)}};var zt=(e,t,r)=>{if(e.plugins.size!==0)for(let n of e.plugins.values()){let s=n.hooks?.[t];if(s)try{s(r)}catch(i){let c=i instanceof Error?i:new Error(String(i));e.onError?e.onError(c,{operation:`plugin:${n.name}:${t}`,key:r.key}):e.silent||console.error(`[gState] Plugin "${n.name}" error:`,i)}}},Tt=(e,t,r)=>{try{e.plugins.set(t.name,t),t.hooks?.onInstall?.({store:r})}catch(n){let s=n instanceof Error?n:new Error(String(n));e.onError?e.onError(s,{operation:"plugin:install",key:t.name}):e.silent||console.error(`[gState] Failed to install plugin "${t.name}": `,n)}};var Oe={local:()=>typeof window<"u"?window.localStorage:null,session:()=>typeof window<"u"?window.sessionStorage:null,memory:()=>{let e=new Map;return{getItem:t=>e.get(t)||null,setItem:(t,r)=>e.set(t,r),removeItem:t=>e.delete(t),key:t=>Array.from(e.keys())[t]||null,get length(){return e.size}}}},Re=e=>{let t=new Map,r=new Map,n=new Map,s=new Set,i=new Map,c=new Set,l=new Map,_=new Map,y=new Map,x=new Map,z=new Map,C=new Map,p=new Map,S=new Map,P=e?.namespace||"gstate",b=e?.silent??!1,ie=e?.debounceTime??150,D=e?.version??0,m=e?.storage||Oe.local(),E=e?.onError,h=e?.maxObjectSize??0,A=e?.maxTotalSize??0,O=e?.encryptionKey??null,ae=e?.validateInput??!0,Vt=e?.auditEnabled??!0,J=e?.userId,ce=e?.immer??!0,Nt=e?.persistByDefault??e?.persistence??e?.persist??!1;e?.accessRules&&e.accessRules.forEach(o=>xe(p,o.pattern,o.permissions));let De=!1,Ie=!1,ze=!1,T=0,B=null,U=null,Te,Ft=new Promise(o=>{Te=o}),Ut=()=>`${P}_`,ot=()=>({store:t,versions:r,sizes:n,totalSize:T,storage:m,config:e||{},diskQueue:z,encryptionKey:O,audit:L,onError:E,silent:b,debounceTime:ie,currentVersion:D}),st=()=>({plugins:x,onError:E,silent:b}),Ve=o=>{if(o==null)return 0;let a=typeof o;if(a==="boolean")return 4;if(a==="number")return 8;if(a==="string")return o.length*2;if(a!=="object")return 0;let u=0,d=[o],g=new WeakSet;for(;d.length>0;){let f=d.pop();if(typeof f=="boolean")u+=4;else if(typeof f=="number")u+=8;else if(typeof f=="string")u+=f.length*2;else if(typeof f=="object"&&f!==null){let w=f;if(g.has(w))continue;if(g.add(w),Array.isArray(w))for(let R=0;R<w.length;R++)d.push(w[R]);else for(let R of Object.keys(w))u+=R.length*2,d.push(w[R])}}return u},$=(o,a)=>{zt(st(),o,a)},L=(o,a,u,d)=>{Vt&&Xe()&&ne&&ne({timestamp:Date.now(),action:o,key:a,userId:J,success:u,error:d})},it=o=>{let a=_.get(o);if(!a)return;let u=new Set,d=f=>(u.add(f),_.has(f)?_.get(f).lastValue:v.get(f)),g=a.selector(d);a.deps.forEach(f=>{if(!u.has(f)){let w=y.get(f);w&&(w.delete(o),w.size===0&&y.delete(f))}}),u.forEach(f=>{a.deps.has(f)||(y.has(f)||y.set(f,new Set),y.get(f).add(o))}),a.deps=u,se(a.lastValue,g)||(a.lastValue=ce&&g!==null&&typeof g=="object"?F(K(g),!0):g,r.set(o,(r.get(o)||0)+1),Q(o))},Q=o=>{if(o){if(y.has(o)){let d=y.get(o);for(let g of d)it(g)}let a=l.get(o);if(a){let d=v.get(o);for(let g of a)try{g(d)}catch(f){let w=f instanceof Error?f:new Error(String(f));E?E(w,{operation:"watcher",key:o}):b||console.error(`[gState] Watcher error for "${o}":`,f)}}let u=i.get(o);if(u)for(let d of u)try{d()}catch(g){let f=g instanceof Error?g:new Error(String(g));E?E(f,{operation:"keyListener",key:o}):b||console.error(`[gState] Listener error for "${o}":`,g)}}if(De){Ie=!0;return}for(let a of s)try{a()}catch(u){let d=u instanceof Error?u:new Error(String(u));E?E(d,{operation:"listener"}):b||console.error("[gState] Global listener error: ",u)}},at=async()=>{Dt(ot())},ue={},v={_setSilently:(o,a)=>{let u=n.get(o)||0,d=ce&&a!==null&&typeof a=="object"?F(K(a),!0):a,f=(h>0||A>0)&&!1?Ve(d):0;T=T-u+f,n.set(o,f),t.set(o,d),r.set(o,(r.get(o)||0)+1),U=null},_registerMethod:(o,a,u)=>{let d=g=>g==="__proto__"||g==="constructor"||g==="prototype";if(d(o)||d(a)){console.warn("[gState] Refusing to register method with unsafe key:",o,a);return}ue[o]||(ue[o]={}),ue[o][a]=u},set:(o,a,u={})=>{let d=t.get(o),g=ce&&typeof a=="function"?kt(d,a):a;if(ae&&!Ye(o))return b||console.warn(`[gState] Invalid key: ${o}`),!1;if(!oe(p,o,"write",J))return L("set",o,!1,"RBAC Denied"),b||console.error(`[gState] RBAC Denied for "${o}"`),!1;let f=ae?re(g):g,w=n.get(o)||0;$("onBeforeSet",{key:o,value:f,store:v,version:r.get(o)||0});let R=ce&&f!==null&&typeof f=="object"?F(K(f),!0):f;if(!se(d,R)){let q=(h>0||A>0)&&!1?Ve(R):0;if(h>0&&q>h){let X=new Error(`Object size (${q} bytes) exceeds maxObjectSize (${h} bytes)`);E?E(X,{operation:"set",key:o}):b||console.warn(`[gState] ${X.message} for "${o}"`)}if(A>0){let X=T-w+q;if(X>A){let lt=new Error(`Total store size (${X} bytes) exceeds limit (${A} bytes)`);E?E(lt,{operation:"set"}):b||console.warn(`[gState] ${lt.message}`)}}T=T-w+q,n.set(o,q),t.set(o,R),r.set(o,(r.get(o)||0)+1),U=null;let ut=u.persist??Nt;return ut&&(z.set(o,{value:R,options:{...u,persist:ut,encoded:u.encoded||e?.encoded}}),B&&clearTimeout(B),B=setTimeout(at,ie)),$("onSet",{key:o,value:R,store:v,version:r.get(o)}),L("set",o,!0),Q(o),!0}return!1},get:o=>{if(!oe(p,o,"read",J))return L("get",o,!1,"RBAC Denied"),null;let a=t.get(o);return $("onGet",{store:v,key:o,value:a}),L("get",o,!0),a},compute:(o,a)=>{try{return _.has(o)||(_.set(o,{selector:a,lastValue:null,deps:new Set}),it(o)),_.get(o).lastValue}catch(u){let d=u instanceof Error?u:new Error(String(u));return E?E(d,{operation:"compute",key:o}):b||console.error(`[gState] Compute error for "${o}": `,u),null}},watch:(o,a)=>{l.has(o)||l.set(o,new Set);let u=l.get(o);return u.add(a),()=>{u.delete(a),u.size===0&&l.delete(o)}},remove:o=>{if(!oe(p,o,"delete",J))return L("delete",o,!1,"RBAC Denied"),!1;let a=t.get(o),u=t.delete(o);return u&&(T-=n.get(o)||0,n.delete(o),$("onRemove",{store:v,key:o,value:a}),U=null),r.set(o,(r.get(o)||0)+1),m&&m.removeItem(`${Ut()}${o}`),L("delete",o,!0),Q(o),u},delete:o=>v.remove(o),deleteAll:()=>{if(Array.from(t.keys()).forEach(o=>v.remove(o)),m){let o=P+"_";for(let a=0;a<(m.length||0);a++){let u=m.key(a);u?.startsWith(o)&&(m.removeItem(u),a--)}}return T=0,n.clear(),U=null,!0},list:()=>Object.fromEntries(t.entries()),use:o=>{c.add(o)},transaction:o=>{De=!0,$("onTransaction",{store:v,key:"START"});try{o()}finally{De=!1,$("onTransaction",{store:v,key:"END"}),Ie&&(Ie=!1,Q())}},destroy:()=>{B&&(clearTimeout(B),B=null),z.clear(),typeof window<"u"&&window.removeEventListener("beforeunload",ct),$("onDestroy",{store:v}),s.clear(),i.clear(),l.clear(),_.clear(),y.clear(),x.clear(),t.clear(),n.clear(),T=0,p.clear(),S.clear(),r.clear(),C.clear(),c.clear()},_addPlugin:o=>{Tt(st(),o,v)},_removePlugin:o=>{x.delete(o)},_subscribe:(o,a)=>{if(a){i.has(a)||i.set(a,new Set);let u=i.get(a);return u.add(o),()=>{u.delete(o),u.size===0&&i.delete(a)}}return s.add(o),()=>s.delete(o)},_getVersion:o=>r.get(o)??0,addAccessRule:(o,a)=>xe(p,o,a),hasPermission:(o,a,u)=>{if(p.size===0)return!0;for(let[d,g]of p){let f;if(typeof d=="function")f=d(o,u);else try{let w=C.get(d);w||(w=new RegExp(d),C.set(d,w)),f=w.test(o)}catch{continue}if(f)return g.includes(a)||g.includes("admin")}return!1},recordConsent:(o,a,u)=>Ae(S,o,a,u),hasConsent:(o,a)=>Ze(S,o,a),getConsents:o=>tt(S,o),revokeConsent:(o,a)=>et(S,o,a),exportUserData:o=>rt(S,o),deleteUserData:o=>nt(S,o),getSnapshot:()=>(U||(U=Object.fromEntries(t.entries())),U),get plugins(){return ue},get isReady(){return ze},get namespace(){return P},get userId(){return J},whenReady:()=>Ft};["addAccessRule","recordConsent","hasConsent","getConsents","revokeConsent","exportUserData","deleteUserData"].forEach(o=>{let a=v[o];a&&v._registerMethod("security",o,a)});let ct=()=>{z.size>0&&at()};return typeof window<"u"&&window.addEventListener("beforeunload",ct),m?It(ot(),o=>(h>0||A>0)&&!1?Ve(o):0,()=>{ze=!0,U=null,Te(),Q()}).then(()=>{}):(ze=!0,Te()),v};var Er=(e,t)=>Re({...t,storage:e}),Cr=e=>Re({...e,storage:Oe.memory()}),Pr=e=>{let t=Oe.session();return t?Re({...e,storage:t}):null};export{ke as Security,Oe as StorageAdapters,Cr as createMemoryStore,Pr as createSessionStore,Re as createStore,Er as createStoreWithStorage};
|
/package/{LICENSE → LICENSE.md}
RENAMED
|
File without changes
|