├── .prettierignore ├── .gitignore ├── .prettierrc ├── tsconfig.json ├── preact ├── package.json └── dist │ ├── gundb-react-hooks.modern.js │ └── gundb-react-hooks.modern.js.map ├── LICENSE.md ├── package.json ├── docs ├── AuthProvider.md ├── useAuth.md ├── useGunState.md ├── useGunKeyAuth.md ├── useGunNamespace.md ├── useGunCollectionStatePaginated.md ├── useGunCollectionState.md ├── useGunOnNodeUpdated.md ├── useGunKeys.md └── useGun.md ├── CHANGELOG.md ├── dist └── index.d.ts └── README.md /.prettierignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .rts2* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noImplicitAny": false, 16 | "noEmit": true 17 | }, 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@altrx/gundb-react-hooks", 3 | "version": "0.9.8", 4 | "description": "GUNDB hooks for React/Preact", 5 | "scripts": {}, 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/alterx/gundb-react-hooks.git" 9 | }, 10 | "author": "Carlos Vega", 11 | "license": "MIT", 12 | "bugs": { 13 | "url": "https://github.com/alterx/gundb-react-hooks/issues" 14 | }, 15 | "sideEffects": false, 16 | "browser": "dist/gundb-react-hooks.umd.js", 17 | "umd:main": "dist/gundb-react-hooks.umd.js", 18 | "jsnext:main": "dist/gundb-react-hooks.modern.js", 19 | "main": "dist/gundb-react-hooks.js", 20 | "module": "dist/gundb-react-hooks.module.js", 21 | "unpkg": "dist/gundb-react-hooks.umd.js", 22 | "source": "./src/index.ts", 23 | "types": "./dist/index.d.ts", 24 | "typings": "./dist/index.d.ts", 25 | "peerDependencies": { 26 | "preact": ">=10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2020 Carlos Vega 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@altrx/gundb-react-hooks", 3 | "version": "1.0.0rc3", 4 | "description": "Type-safe, performant GunDB hooks for React/Preact with authentication, error handling, and debugging utilities", 5 | "browser": "./dist/gundb-react-hooks.umd.js", 6 | "umd:main": "./dist/gundb-react-hooks.umd.js", 7 | "jsnext:main": "./dist/gundb-react-hooks.modern.js", 8 | "main": "./dist/gundb-react-hooks.js", 9 | "module": "./dist/gundb-react-hooks.module.js", 10 | "unpkg": "./dist/gundb-react-hooks.umd.js", 11 | "source": "./src/index.ts", 12 | "types": "./dist/index.d.ts", 13 | "typings": "./dist/index.d.ts", 14 | "exports": { 15 | ".": { 16 | "types": "./dist/index.d.ts", 17 | "import": "./dist/gundb-react-hooks.module.js", 18 | "require": "./dist/gundb-react-hooks.js" 19 | }, 20 | "./preact": { 21 | "types": "./preact/dist/index.d.ts", 22 | "import": "./preact/dist/gundb-react-hooks.module.js", 23 | "require": "./preact/dist/gundb-react-hooks.js" 24 | } 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git+https://github.com/alterx/gundb-react-hooks.git" 29 | }, 30 | "keywords": [ 31 | "preact", 32 | "react", 33 | "gun", 34 | "gunDB", 35 | "graph", 36 | "document", 37 | "key", 38 | "value", 39 | "relational", 40 | "datastore", 41 | "database", 42 | "engine", 43 | "realtime", 44 | "decentralized", 45 | "peer-to-peer", 46 | "distributed", 47 | "P2P", 48 | "OSS", 49 | "embedded", 50 | "localstorage", 51 | "S3", 52 | "typescript", 53 | "hooks", 54 | "error-handling", 55 | "type-safe", 56 | "performance", 57 | "debugging", 58 | "authentication", 59 | "auth", 60 | "login", 61 | "keypair", 62 | "sea", 63 | "cryptography" 64 | ], 65 | "files": [ 66 | "dist", 67 | "preact/dist" 68 | ], 69 | "scripts": { 70 | "build": "rimraf dist && npm run build:preact && npm run build:react", 71 | "build:react": "microbundle --define process.env.NODE_ENV=production --external react --name @altrx/gundb-react-hooks --no-compress --output dist/", 72 | "build:preact": "microbundle --define process.env.NODE_ENV=production --external preact --name @altrx/gundb-react-hooks --no-compress --output preact/dist --alias react=preact/hooks", 73 | "dev": "microbundle watch", 74 | "test": "echo \"Error: no test specified\" && exit 1" 75 | }, 76 | "author": "Carlos Vega", 77 | "license": "MIT", 78 | "peerDependencies": { 79 | "react": ">=16.12.0", 80 | "react-dom": ">=16.12.0" 81 | }, 82 | "devDependencies": { 83 | "@skypack/package-check": "^0.2.2", 84 | "husky": "^9.1.7", 85 | "microbundle": "^0.15.1", 86 | "prettier": "^3.4.2", 87 | "pretty-quick": "^4.0.0", 88 | "react": "^16.13.1", 89 | "react-dom": "^16.13.1", 90 | "rimraf": "^6.0.1" 91 | }, 92 | "husky": { 93 | "hooks": { 94 | "pre-commit": "pretty-quick --staged" 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /docs/AuthProvider.md: -------------------------------------------------------------------------------- 1 | # AuthProvider 2 | 3 | A React context provider that manages GunDB authentication state, key generation, and secure storage across your application. 4 | 5 | ## Overview 6 | 7 | `AuthProvider` automatically handles key pair generation, secure storage, authentication flow, and cross-platform storage abstraction. It serves as the foundation for the authentication system in GunDB React applications. 8 | 9 | ## API Reference 10 | 11 | ### Props 12 | 13 | #### Required Props 14 | 15 | | Prop | Type | Description | 16 | | ---------- | ----------------- | -------------------------------------------------- | 17 | | `Gun` | `any` | Gun constructor function | 18 | | `sea` | `any` | SEA (Security, Encryption, Authorization) instance | 19 | | `storage` | `Storage` | Storage implementation for key persistence | 20 | | `gunOpts` | `GunOptions` | Configuration options for Gun instance | 21 | | `children` | `React.ReactNode` | Child components to wrap | 22 | 23 | #### Optional Props 24 | 25 | | Prop | Type | Default | Description | 26 | | -------------- | -------- | -------- | ---------------------------------------- | 27 | | `keyFieldName` | `string` | `'keys'` | Storage key name for persisting keypairs | 28 | 29 | ### Storage Interface 30 | 31 | ```typescript 32 | interface Storage { 33 | getItem: (key: string) => any; 34 | setItem: (key: string, data: string) => any; 35 | removeItem: (key: string) => any; 36 | } 37 | ``` 38 | 39 | ## Basic Usage 40 | 41 | ### Simple Setup 42 | 43 | ```typescript 44 | import { AuthProvider } from '@altrx/gundb-react-hooks'; 45 | import Gun from 'gun'; 46 | import 'gun/sea'; 47 | 48 | function App() { 49 | return ( 50 | 59 | 60 | 61 | ); 62 | } 63 | ``` 64 | 65 | ## Advanced Usage 66 | 67 | ### Platform-Specific Storage 68 | 69 | ### Web (localStorage) 70 | 71 | ```typescript 72 | 76 | ``` 77 | 78 | ### React Native (AsyncStorage) 79 | 80 | ```typescript 81 | import AsyncStorage from '@react-native-async-storage/async-storage'; 82 | 83 | const asyncStorage = { 84 | getItem: async (key: string) => { 85 | return await AsyncStorage.getItem(key); 86 | }, 87 | setItem: async (key: string, data: string) => { 88 | await AsyncStorage.setItem(key, data); 89 | }, 90 | removeItem: async (key: string) => { 91 | await AsyncStorage.removeItem(key); 92 | } 93 | }; 94 | 95 | 99 | ``` 100 | 101 | ### Node.js (File System) 102 | 103 | ```typescript 104 | import fs from 'fs'; 105 | import path from 'path'; 106 | 107 | const fileStorage = { 108 | getItem: (key: string) => { 109 | try { 110 | const filePath = path.join(__dirname, `${key}.json`); 111 | return fs.readFileSync(filePath, 'utf8'); 112 | } catch { 113 | return null; 114 | } 115 | }, 116 | setItem: (key: string, data: string) => { 117 | const filePath = path.join(__dirname, `${key}.json`); 118 | fs.writeFileSync(filePath, data); 119 | }, 120 | removeItem: (key: string) => { 121 | const filePath = path.join(__dirname, `${key}.json`); 122 | try { 123 | fs.unlinkSync(filePath); 124 | } catch { 125 | // File doesn't exist, ignore 126 | } 127 | } 128 | }; 129 | 130 | 134 | ``` 135 | 136 | ### Secure Storage (Encrypted) 137 | 138 | ```typescript 139 | import CryptoJS from 'crypto-js'; 140 | 141 | const secureStorage = { 142 | getItem: (key: string) => { 143 | const encrypted = localStorage.getItem(key); 144 | if (!encrypted) return null; 145 | 146 | try { 147 | const decrypted = CryptoJS.AES.decrypt(encrypted, 'your-secret-key'); 148 | return decrypted.toString(CryptoJS.enc.Utf8); 149 | } catch { 150 | return null; 151 | } 152 | }, 153 | setItem: (key: string, data: string) => { 154 | const encrypted = CryptoJS.AES.encrypt(data, 'your-secret-key').toString(); 155 | localStorage.setItem(key, encrypted); 156 | }, 157 | removeItem: (key: string) => { 158 | localStorage.removeItem(key); 159 | } 160 | }; 161 | 162 | 166 | ``` 167 | 168 | ## Error Handling 169 | 170 | ### Comprehensive Error Management 171 | 172 | ```typescript 173 | function AppWithErrorHandling() { 174 | return ( 175 | 176 | 182 | 183 | 184 | 185 | ); 186 | } 187 | 188 | class ErrorBoundary extends React.Component { 189 | componentDidCatch(error: Error, errorInfo: any) { 190 | if (error.message.includes('Provide gunOpts, Gun and sea')) { 191 | console.error('AuthProvider configuration error:', error); 192 | // Handle configuration errors 193 | } 194 | } 195 | 196 | render() { 197 | // Error UI 198 | return this.state.hasError ? : this.props.children; 199 | } 200 | } 201 | ``` 202 | 203 | ## Migration from v0.9.x 204 | 205 | ### Before (v0.9.x) 206 | 207 | ```typescript 208 | // Manual provider setup with limited features 209 | import { GunProvider } from '@altrx/gundb-react-auth'; 210 | 211 | 212 | 213 | 214 | ``` 215 | 216 | ### After (v1.0.0) 217 | 218 | ```typescript 219 | // Enhanced provider with built-in authentication 220 | import { AuthProvider } from '@altrx/gundb-react-hooks'; 221 | 222 | 228 | 229 | 230 | ``` 231 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [1.0.0rc3] - 2025-08-22 9 | 10 | ### Fixed 11 | 12 | - exports in package.json 13 | 14 | ## [1.0.0rc2] - 2025-08-22 15 | 16 | ### Fixed 17 | 18 | - Performance and compatibility issues. 19 | 20 | ## [1.0.0rc1] - 2025-08-21 21 | 22 | ### Added 23 | 24 | - **`useGunCollectionStatePaginated`** - A high-performance, memory-efficient hook for managing paginated GunDB collections with smart caching, real-time updates, and comprehensive filtering/sorting capabilities. 25 | 26 | ### Documentation 27 | 28 | - Removed unused migration references 29 | 30 | ## [1.0.0] - 2025-08-21 31 | 32 | ### Major Release - Complete Rewrite 33 | 34 | This release represents a significant overhaul of the library with breaking changes, improved TypeScript support, and enhanced developer experience. 35 | It also consolidates the hooks and providers available at https://github.com/alterx/gundb-react-auth to provide an all emcompasing solution for GunDB and React integration. 36 | 37 | ### Added 38 | 39 | #### Type Safety 40 | 41 | - **Comprehensive TypeScript definitions** for all GunDB operations 42 | - **Proper interface definitions** (`IGunChainReference`, `IGunUserReference`) 43 | - **Strong type constraints** with `ValidGunData` and `NodeData` 44 | - **Enhanced error types** with contextual information (`GunError`) 45 | 46 | #### Error Handling & Reliability 47 | 48 | - **Error states in all hooks** - hooks now return `{ error, isLoading, isConnected }` 49 | - **Input validation** for all operations (validateNodeID, validateData) 50 | - **Connection timeout handling** (5-second timeout with proper error reporting) 51 | - **Graceful failure handling** with try-catch blocks and error recovery 52 | - **Development warnings** for common misconfigurations 53 | 54 | #### Performance Optimizations 55 | 56 | - **Fixed memory leaks** in `useGunOnNodeUpdated` with proper cleanup tracking 57 | - **Memoization** of expensive operations using `useMemo` and `useCallback` 58 | - **Optimized re-renders** with better dependency management 59 | - **Debounced handler cleanup** to prevent memory accumulation 60 | 61 | #### New Hooks & Utilities 62 | 63 | - **`useGunContext`** - Access Gun instance through React context 64 | - **`useGunDebug`** - Development debugging with detailed logging 65 | - **`useGunConnection`** - Monitor connection status and health 66 | - **`GunProvider`** - Context provider for Gun instance management 67 | - **`AuthProvider`** - Authentication provider with key management and storage (from https://github.com/alterx/gundb-react-auth) 68 | - **`useAuth`** - Hook for accessing authentication state and methods (from https://github.com/alterx/gundb-react-auth) 69 | 70 | #### Enhanced Existing Hooks 71 | 72 | - **`useGunState`** now returns `{ fields, put, remove, error, isLoading, isConnected }` 73 | - **`useGunCollectionState`** now returns `{ collection, items, addToSet, updateInSet, removeFromSet, error, isLoading, count }` 74 | - **`useGunKeyAuth`** now returns `[namespace, isLoggedIn, error]` with proper error handling 75 | - **`useGunOnNodeUpdated`** has improved memory management and error handling 76 | 77 | #### Developer Experience 78 | 79 | - **Comprehensive development warnings** for configuration issues 80 | - **Better debugging capabilities** with timestamped logs and context 81 | - **Improved error messages** with specific context about where errors occurred 82 | - **Type-safe operations** with IDE autocomplete and error detection 83 | - **Integrated authentication system** with automatic key storage and retrieval 84 | - **Storage abstraction** for flexible key persistence (localStorage, AsyncStorage, etc.) 85 | 86 | ### Changed 87 | 88 | #### Breaking Changes 89 | 90 | - **Hook return types** now include error and loading states 91 | - **`useGunKeyAuth`** now returns a tuple with error as third element 92 | - **Collection hooks** now provide both `collection` (Map) and `items` (Array) 93 | - **Error handling** is now explicit rather than silent failures 94 | 95 | #### API Improvements 96 | 97 | - **More intuitive return objects** with consistent naming 98 | - **Better function signatures** with proper TypeScript constraints 99 | - **Enhanced validation** for all user inputs 100 | - **Consistent error reporting** across all hooks 101 | 102 | ### Fixed 103 | 104 | #### Critical Fixes 105 | 106 | - **Memory leaks** in listener cleanup (useGunOnNodeUpdated) 107 | - **Race conditions** in mount/unmount scenarios 108 | - **Silent failures** in async operations 109 | - **Improper error propagation** from GunDB callbacks 110 | 111 | #### Type Safety Fixes 112 | 113 | - **Removed extensive use of `any` types** (reduced by ~90%) 114 | - **Fixed generic type constraints** for better IDE support 115 | - **Proper nullable types** for optional parameters 116 | - **Enhanced type inference** for hook return values 117 | 118 | ### Infrastructure 119 | 120 | #### Development Tools 121 | 122 | - **Enhanced debugging utilities** for development workflow 123 | - **Better error boundaries** and error handling patterns 124 | - **Improved development warnings** system 125 | - **Type-safe development helpers** 126 | 127 | #### Build & Distribution 128 | 129 | - **Updated package metadata** with new keywords and description 130 | - **Better TypeScript integration** with proper type exports 131 | - **Enhanced module resolution** for both React and Preact 132 | 133 | ### Documentation 134 | 135 | #### New Documentation and Updated Examples 136 | 137 | - **Migration documentation** 138 | - **TypeScript examples** in all documentation 139 | - **Error handling patterns** and best practices 140 | - **Type-safe examples** with proper error handling 141 | - **Real-world usage patterns** with context providers 142 | - **Performance optimization examples** 143 | - **Debugging and development workflows** 144 | 145 | ### Migration Guide 146 | 147 | #### From v0.9.x to v1.0.0 148 | 149 | For detailed migration instructions and compatibility information, see the detailed documentation for each hook. 150 | 151 | ### Performance Improvements 152 | 153 | - **Reduced unnecessary re-renders** through better memoization and dependency management 154 | - **Fixed memory leaks** in listener cleanup and component unmounting 155 | - **Eliminated uncleaned timeout handlers** in continuous testing scenarios 156 | - **Improved bundle size** with better tree shaking 157 | 158 | ### Development Experience 159 | 160 | - **Significantly reduced common development errors** through TypeScript definitions 161 | - **Enhanced IDE support** with proper TypeScript definitions 162 | - **Better debugging capabilities** with contextual logging 163 | - **Comprehensive error messages** with actionable information 164 | 165 | --- 166 | 167 | ## [0.9.8] - Previous Release 168 | 169 | ### Features 170 | 171 | - Basic GunDB React hooks implementation 172 | - Support for React and Preact 173 | - Encryption/decryption utilities 174 | - Real-time updates with debouncing 175 | - Collection state management 176 | 177 | ### Known Issues (Fixed in v1.0.0) 178 | 179 | - Memory leaks in listener cleanup 180 | - Limited TypeScript support 181 | - Silent error failures 182 | - Missing development tools 183 | - Performance optimization opportunities 184 | 185 | --- 186 | 187 | ## Migration Support 188 | 189 | For detailed migration instructions and compatibility information, see the detailed documentation for each hook. 190 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export interface IGunChainReference { 3 | get(key: string): IGunChainReference; 4 | put(data: T, callback?: (ack: { 5 | err?: string; 6 | ok?: any; 7 | }) => void): IGunChainReference; 8 | on(callback: (data: T, key: string, message?: any, event?: any) => void): () => void; 9 | once(callback: (data: T, key: string) => void): void; 10 | set(data: T, callback?: (ack: { 11 | err?: string; 12 | ok?: any; 13 | }) => void): IGunChainReference; 14 | map(): IGunChainReference; 15 | open?(callback: (data: T, key: string, message?: any, event?: any) => void): void; 16 | user(soul?: string): IGunUserReference; 17 | off(): void; 18 | toString(): string; 19 | } 20 | export interface IGunUserReference extends IGunChainReference { 21 | is: KeyPair | null; 22 | auth(keypair: KeyPair, callback?: (ack: any) => void): void; 23 | create(keypair: KeyPair, callback?: (ack: any) => void): void; 24 | leave(): void; 25 | } 26 | export interface GunError { 27 | err: string; 28 | code?: string | number; 29 | context?: string; 30 | } 31 | export type ValidGunData = string | number | boolean | object | null; 32 | export type GunStatic = any; 33 | export type GunRef = IGunChainReference | null; 34 | export type NamespacedRef = IGunUserReference; 35 | export type KeyPair = { 36 | pub: string; 37 | priv: string; 38 | epub: string; 39 | epriv: string; 40 | }; 41 | export type Storage = { 42 | getItem: (key: string) => any; 43 | setItem: (key: string, data: string) => any; 44 | removeItem: (key: string) => any; 45 | }; 46 | export type AuthContextType = { 47 | gun: IGunChainReference; 48 | user: IGunUserReference; 49 | login: (keys?: undefined | string | KeyPair) => void; 50 | logout: (onLoggedOut?: () => void) => void; 51 | sea: any; 52 | appKeys: undefined | string | KeyPair; 53 | isLoggedIn: boolean; 54 | newGunInstance: (opts?: GunOptions) => IGunChainReference; 55 | }; 56 | export type AuthProviderOpts = { 57 | Gun: any; 58 | sea: any; 59 | keyFieldName?: string; 60 | storage: Storage; 61 | gunOpts: GunOptions; 62 | children: React.ReactNode; 63 | }; 64 | export type Options = { 65 | appKeys?: undefined | string | KeyPair; 66 | sea?: any; 67 | interval?: number; 68 | useOpen?: boolean; 69 | }; 70 | export type NodeData = T & { 71 | readonly nodeID: string; 72 | readonly _?: { 73 | '#': string; 74 | '>': Record; 75 | }; 76 | }; 77 | export type NodeT = T & { 78 | nodeID: string; 79 | [key: string]: any; 80 | }; 81 | export type ActionType = { 82 | type: 'add'; 83 | data: NodeT | NodeT[]; 84 | } | { 85 | type: 'update'; 86 | data: NodeT; 87 | } | { 88 | type: 'remove'; 89 | data: { 90 | nodeID: string; 91 | }; 92 | }; 93 | export type UpdateType = { 94 | id: string; 95 | data: any; 96 | }; 97 | export interface GunOptions extends Partial<{ 98 | file: string; 99 | web: any; 100 | s3: { 101 | key: any; 102 | secret: any; 103 | bucket: any; 104 | }; 105 | peers: string[] | Record; 106 | radisk: boolean; 107 | localStorage: boolean; 108 | uuid(): string; 109 | [key: string]: any; 110 | }> { 111 | } 112 | export interface CollectionState { 113 | collection: Map; 114 | sorted?: T[]; 115 | infiniteScrolling?: { 116 | isFetching: boolean; 117 | lastFetched: string; 118 | reverse: boolean; 119 | }; 120 | } 121 | export interface UseGunStateReturn { 122 | fields: T; 123 | put: (data: Partial) => Promise; 124 | remove: (field: string) => Promise; 125 | error: GunError | null; 126 | isLoading: boolean; 127 | isConnected: boolean; 128 | } 129 | export interface UseGunCollectionReturn { 130 | collection: Map>; 131 | items: NodeT[]; 132 | addToSet: (data: T, nodeID?: string) => Promise; 133 | updateInSet: (nodeID: string, data: Partial) => Promise; 134 | removeFromSet: (nodeID: string) => Promise; 135 | error: GunError | null; 136 | isLoading: boolean; 137 | count: number; 138 | } 139 | export interface PaginationOptions extends Options { 140 | pageSize?: number; 141 | currentPage?: number; 142 | sortBy?: keyof T | ((a: NodeT, b: NodeT) => number); 143 | sortOrder?: 'asc' | 'desc'; 144 | filter?: (item: NodeT) => boolean; 145 | preloadPages?: number; 146 | } 147 | export interface UsePaginatedCollectionReturn extends UseGunCollectionReturn { 148 | currentPage: number; 149 | totalPages: number; 150 | hasNextPage: boolean; 151 | hasPrevPage: boolean; 152 | pageSize: number; 153 | nextPage: () => void; 154 | prevPage: () => void; 155 | goToPage: (page: number) => void; 156 | setPageSize: (size: number) => void; 157 | currentPageItems: NodeT[]; 158 | currentPageCount: number; 159 | isLoadingPage: boolean; 160 | preloadedPages: Set; 161 | } 162 | export declare const encryptData: (data: any, keys: undefined | string | KeyPair, sea: any) => Promise; 163 | export declare const decryptData: (data: any, keys: undefined | string | KeyPair, sea: any) => Promise; 164 | export declare const debouncedUpdates: (dispatcher: any, type?: string, timeout?: number) => { 165 | (update: UpdateType): () => void; 166 | cleanup(): void; 167 | }; 168 | export declare const useIsMounted: () => any; 169 | export declare const nodeReducer: (state: NodeT, { data, type }: ActionType) => T; 170 | export declare const collectionReducer: (state: CollectionState, { data, type }: ActionType) => CollectionState; 171 | export declare const useSafeReducer: (reducer: any, initialState: T) => [T, Function]; 172 | export declare const useGun: (Gun: GunStatic, opts: GunOptions) => any; 173 | export declare const useGunNamespace: (gun: GunRef, soul?: string) => any; 174 | export declare const useGunKeyAuth: (gun: GunRef, keys: KeyPair, triggerAuth?: boolean) => readonly [any, any, any]; 175 | export declare const useGunKeys: (sea: any, existingKeys?: KeyPair | undefined | null) => any; 176 | export declare const useGunOnNodeUpdated: (ref: GunRef, opts: Options | undefined, cb: (data: T, nodeID: string) => void, cleanup?: () => void) => void; 177 | export declare const useGunState: (ref: GunRef, opts?: Options) => UseGunStateReturn; 178 | export declare const useGunCollectionState: >(ref: GunRef, opts?: Options) => UseGunCollectionReturn; 179 | export declare const useGunCollectionStatePaginated: >(ref: GunRef, paginationOpts?: PaginationOptions) => UsePaginatedCollectionReturn; 180 | export declare const AuthContext: any; 181 | export declare const AuthProvider: React.FC; 182 | export declare const useAuth: () => AuthContextType; 183 | export declare const GunContext: any; 184 | export declare const GunProvider: React.FC<{ 185 | gun: GunStatic; 186 | options: GunOptions; 187 | children: React.ReactNode; 188 | }>; 189 | export declare const useGunContext: () => IGunChainReference; 190 | export declare const useGunDebug: (ref: IGunChainReference | null, label: string, enabled?: boolean) => void; 191 | export declare const useGunConnection: (ref: IGunChainReference) => { 192 | isConnected: boolean; 193 | lastSeen: Date | null; 194 | error: GunError | null; 195 | }; 196 | -------------------------------------------------------------------------------- /docs/useAuth.md: -------------------------------------------------------------------------------- 1 | # useAuth 2 | 3 | A comprehensive authentication hook for GunDB applications that provides automatic key generation, storage management, and authentication state tracking. 4 | 5 | ## Overview 6 | 7 | The `useAuth` hook provides a complete authentication solution for GunDB applications, managing user keys, authentication state, and secure storage automatically. It integrates seamlessly with the `AuthProvider` component to deliver a robust authentication system. 8 | 9 | ## API Reference 10 | 11 | ### Signature 12 | 13 | ```typescript 14 | useAuth(): AuthContextType 15 | ``` 16 | 17 | ### Return Type 18 | 19 | ```typescript 20 | interface AuthContextType { 21 | gun: IGunChainReference; // Gun instance 22 | user: IGunUserReference; // Authenticated user reference 23 | login: (keys?: KeyPair | string) => void; // Login function 24 | logout: (onLoggedOut?: () => void) => void; // Logout function 25 | sea: any; // SEA instance 26 | appKeys: KeyPair | string | undefined; // Current keys 27 | isLoggedIn: boolean; // Authentication status 28 | newGunInstance: (opts?: GunOptions) => IGunChainReference; // Create new Gun instance 29 | } 30 | ``` 31 | 32 | ## Basic Usage 33 | 34 | ```typescript 35 | import { AuthProvider, useAuth } from '@altrx/gundb-react-hooks'; 36 | import Gun from 'gun'; 37 | import 'gun/sea'; 38 | 39 | // Wrap your app with AuthProvider 40 | function App() { 41 | return ( 42 | 48 | 49 | 50 | ); 51 | } 52 | 53 | // Use authentication in components 54 | function AuthenticatedApp() { 55 | const { 56 | user, 57 | login, 58 | logout, 59 | isLoggedIn, 60 | appKeys, 61 | gun 62 | } = useAuth(); 63 | 64 | return ( 65 |
66 | {isLoggedIn ? ( 67 |
68 |

Welcome! You are authenticated.

69 |

Your public key: {appKeys?.pub}

70 | 71 |
72 | ) : ( 73 |
74 |

Please log in

75 | 76 |
77 | )} 78 |
79 | ); 80 | } 81 | ``` 82 | 83 | ## Advanced Usage 84 | 85 | ### Custom Storage Implementation 86 | 87 | ```typescript 88 | // For React Native with AsyncStorage 89 | import AsyncStorage from '@react-native-async-storage/async-storage'; 90 | 91 | const asyncStorage = { 92 | getItem: async (key: string) => { 93 | const value = await AsyncStorage.getItem(key); 94 | return value; 95 | }, 96 | setItem: async (key: string, data: string) => { 97 | await AsyncStorage.setItem(key, data); 98 | }, 99 | removeItem: async (key: string) => { 100 | await AsyncStorage.removeItem(key); 101 | } 102 | }; 103 | 104 | 105 | ``` 106 | 107 | ### Login with Existing Keys 108 | 109 | ```typescript 110 | function LoginForm() { 111 | const { login } = useAuth(); 112 | const [keyInput, setKeyInput] = useState(''); 113 | 114 | const handleLogin = () => { 115 | try { 116 | const keys = JSON.parse(keyInput); 117 | login(keys); 118 | } catch (error) { 119 | console.error('Invalid key format:', error); 120 | } 121 | }; 122 | 123 | return ( 124 |
125 |