/** * React Hook Example * * This example shows how to use Cognitum Gate in React applications * with a custom hook for action permission. * * Usage in your React app: * import { useGate, GateProvider } from './react-hook'; */ import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'; import { CognitumGate, GateDecision, ActionContext, PermitResult } from '@cognitum/gate'; // Gate Context interface GateContextValue { gate: CognitumGate | null; isReady: boolean; permitAction: (action: ActionContext) => Promise; pendingActions: Map; } const GateContext = createContext(null); // Gate Provider interface GateProviderProps { children: ReactNode; config?: { minCut?: number; maxShift?: number; storage?: 'memory' | 'indexeddb'; }; } export function GateProvider({ children, config }: GateProviderProps) { const [gate, setGate] = useState(null); const [isReady, setIsReady] = useState(false); const [pendingActions] = useState(new Map()); useEffect(() => { CognitumGate.init({ thresholds: { minCut: config?.minCut ?? 10.0, maxShift: config?.maxShift ?? 0.5, eDeny: 0.01, ePermit: 100.0, }, storage: config?.storage ?? 'indexeddb', }).then((g) => { setGate(g); setIsReady(true); }); }, [config]); const permitAction = useCallback(async (action: ActionContext) => { if (!gate) throw new Error('Gate not initialized'); const result = await gate.permitAction(action); if (result.decision === GateDecision.Defer) { pendingActions.set(result.receiptSequence, action); } return result; }, [gate, pendingActions]); return ( {children} ); } // useGate Hook export function useGate() { const context = useContext(GateContext); if (!context) { throw new Error('useGate must be used within a GateProvider'); } return context; } // usePermitAction Hook - simplified action permission export function usePermitAction() { const { permitAction, isReady } = useGate(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [lastResult, setLastResult] = useState(null); const requestPermit = useCallback(async (action: ActionContext) => { if (!isReady) { setError(new Error('Gate not ready')); return null; } setIsLoading(true); setError(null); try { const result = await permitAction(action); setLastResult(result); return result; } catch (e) { setError(e as Error); return null; } finally { setIsLoading(false); } }, [permitAction, isReady]); return { requestPermit, isLoading, error, lastResult, isReady }; } // Example Component: Protected Button interface ProtectedButtonProps { actionId: string; actionType: string; target: string; onPermitted: (token: string) => void; onDeferred: (sequence: number) => void; onDenied: (reason: string) => void; children: ReactNode; } export function ProtectedButton({ actionId, actionType, target, onPermitted, onDeferred, onDenied, children, }: ProtectedButtonProps) { const { requestPermit, isLoading, error } = usePermitAction(); const handleClick = async () => { const result = await requestPermit({ actionId, actionType, agentId: 'web-user', target, metadata: { timestamp: Date.now() }, }); if (!result) return; switch (result.decision) { case GateDecision.Permit: onPermitted(result.token); break; case GateDecision.Defer: onDeferred(result.receiptSequence); break; case GateDecision.Deny: onDenied(result.reason || 'Action denied'); break; } }; return ( ); } // Example App export function ExampleApp() { const [status, setStatus] = useState(''); return (

Cognitum Gate - React Example

{ setStatus(`✅ Permitted! Token: ${token.slice(0, 20)}...`); }} onDeferred={(seq) => { setStatus(`⏸️ Deferred - Human review needed (seq: ${seq})`); }} onDenied={(reason) => { setStatus(`❌ Denied: ${reason}`); }} > Deploy to Production

{status}

); } // Audit Log Component function AuditLog() { const { gate, isReady } = useGate(); const [receipts, setReceipts] = useState([]); useEffect(() => { if (isReady && gate) { gate.getReceipts(0, 10).then(setReceipts); } }, [gate, isReady]); return (

Recent Decisions

{receipts.map((r) => ( ))}
Seq Action Decision Time
{r.sequence} {r.token.actionId} {r.token.decision} {new Date(r.token.timestamp / 1_000_000).toLocaleString()}
); } export default ExampleApp;