npm package: @photonite/subgraph-sync
Description: React hooks and components for tracking subgraph synchronization states with Apollo Client
Author: Alaa Saleh
Latest version: 1.0.0

# 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