UNPKG

@photonite/subgraph-sync

Version:

React hooks and components for tracking subgraph synchronization states with Apollo Client

275 lines (214 loc) 6.79 kB
# Subgraph Sync A React library for handling subgraph synchronization states with Apollo Client. Track indexing progress, sync states, and ensure your dApp queries return up-to-date data from The Graph. [![Tests](https://img.shields.io/badge/tests-70%20passing-brightgreen)](#tests) [![Coverage](https://img.shields.io/badge/coverage-97.95%25-brightgreen)](#coverage) [![TypeScript](https://img.shields.io/badge/TypeScript-4.5+-blue)](https://www.typescriptlang.org/) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) ## Features - 🔄 **Real-time Sync Tracking** - Monitor subgraph indexing progress - 🎯 **Block & Timestamp Targeting** - Wait for specific blocks or timestamps - ⚡ **Progress Calculation** - Visual progress indicators (0-100%) - 🔁 **Automatic Retries** - Configurable retry logic for failed queries - ⏱️ **Timeout Handling** - Graceful timeout with callbacks - 🎨 **UI Components** - Pre-built React components for sync indicators - 📦 **Context Provider** - Manage multiple transaction sync states - � **Type-Safe** - Full TypeScript support - 🔒 **Type-Safe** - Full TypeScript support ## Installation ```bash npm install subgraph-sync # or yarn add subgraph-sync # or pnpm add subgraph-sync ``` ### Peer Dependencies This library requires the following peer dependencies: ```json { "@apollo/client": "^3.0.0", "graphql": "^15.0.0 || ^16.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } ``` ## Quick Start ### Basic Usage with useSubgraphSync ```tsx import { useSubgraphSync } from "subgraph-sync"; function MyComponent() { const syncState = useSubgraphSync( { blockNumber: 1000000 }, // Target block { pollInterval: 2000 } // Poll every 2 seconds ); if (syncState.isIndexing) { return <div>Syncing... {syncState.progress}%</div>; } if (syncState.isSynced) { return <div>✅ Synced to block {syncState.currentBlock?.number}</div>; } return null; } ``` ### Combined Query + Sync ```tsx import { gql } from "@apollo/client"; import { useSubgraphQuery } from "subgraph-sync"; const GET_USER = gql` query GetUser($id: ID!) { user(id: $id) { id balance } } `; function UserBalance({ userId, targetBlock }) { const { data, loading, isIndexing, isSynced, progress } = useSubgraphQuery( GET_USER, { variables: { id: userId }, targetBlockNumber: targetBlock, } ); if (loading || isIndexing) { return <div>Loading... {progress}%</div>; } return <div>Balance: {data.user.balance}</div>; } ``` ### Using the SyncIndicator Component ```tsx import { useSubgraphSync, SyncIndicator } from "subgraph-sync"; function TransactionTracker({ txHash, blockNumber }) { const syncState = useSubgraphSync({ blockNumber }); return ( <div> <h2>Transaction: {txHash}</h2> <SyncIndicator syncState={syncState} showProgress={true} showBlockInfo={true} /> </div> ); } ``` ## API Reference ### `useSubgraphSync(target, config?)` Track subgraph synchronization to a specific target. **Parameters:** - `target: SyncTarget` - Target block or timestamp - `blockNumber?: number` - Target block number - `timestamp?: number` - Target timestamp - `config?: SyncConfig` - Optional configuration - `pollInterval?: number` - Polling interval in ms (default: 2000) - `timeout?: number` - Timeout in ms (default: 120000) - `maxRetries?: number` - Max retry attempts (default: 3) - `onTimeout?: () => void` - Timeout callback - `onError?: (error: Error) => void` - Error callback - `onSyncComplete?: (status: SubgraphStatus) => void` - Success callback **Returns:** `UseSubgraphSyncResult` ```typescript { isIndexing: boolean; // Currently indexing isSynced: boolean; // Reached target isTimeout: boolean; // Timed out isError: boolean; // Error occurred currentBlock: Block | null; // Current indexed block targetBlock: Block | null; // Target block progress: number; // Progress 0-100 error: string | null; // Error message retries: number; // Retry count refetch: () => Promise<any>; // Manual refetch reset: () => void; // Reset state } ``` ### `useSubgraphQuery(query, options?)` Combines Apollo `useQuery` with sync tracking. **Parameters:** - `query: DocumentNode` - GraphQL query - `options?: QueryWithSyncOptions` - Apollo query options + sync options - `targetBlockNumber?: number` - Target block - `targetTimestamp?: number` - Target timestamp - `syncConfig?: SyncConfig` - Sync configuration - ...all Apollo `useQuery` options **Returns:** All Apollo `QueryResult` properties + `UseSubgraphSyncResult` properties ### `<SyncIndicator />` Pre-built UI component for displaying sync state. **Props:** ```typescript { syncState: UseSubgraphSyncResult; // Required: sync state showProgress?: boolean; // Show progress bar (default: true) showBlockInfo?: boolean; // Show block details (default: true) className?: string; // Additional CSS classes } ``` ## Examples ### Wait for Transaction Confirmation ```tsx import { useSubgraphSync } from "subgraph-sync"; function SendTransaction() { const [targetBlock, setTargetBlock] = useState(null); const syncState = useSubgraphSync( { blockNumber: targetBlock }, { onSyncComplete: () => { console.log("Transaction indexed!"); }, } ); return ( <div> <button onClick={() => setTargetBlock(1000000)}>Send Transaction</button> {syncState.isIndexing && ( <div>Waiting for indexing... {syncState.progress}%</div> )} </div> ); } ``` ### Custom Error Handling ```tsx const syncState = useSubgraphSync( { blockNumber: 1000000 }, { maxRetries: 5, pollInterval: 1000, timeout: 60000, onError: (error) => { console.error("Sync failed:", error); }, onTimeout: () => { console.warn("Sync timeout"); }, } ); ``` ## Testing ```bash npm test # Run all tests npm run test:watch # Watch mode npm run test:coverage # Coverage report ``` ## TypeScript Full TypeScript definitions included: ```typescript import type { SyncConfig, SyncTarget, SyncState, UseSubgraphSyncResult, SubgraphStatus, Block, QueryWithSyncOptions, } from "subgraph-sync"; ``` ## License MIT This library provides: - **Modular architecture** for easy extension - **TypeScript support** for better developer experience - **Flexible configuration** for different use cases - **Pre-built components** for quick integration - **Comprehensive documentation** for easy adoption - **Build system** for distribution