npm package: @mercnet/core
Description: Core utilities and types for MercNet ecosystem
Author: The Rocketeer
Latest version: 0.1.1

# @mercnet/core v1.0

A practical and type-safe GraphQL client and utility library for the MercNet ecosystem. This refined v1 focuses on providing essential tools with excellent TypeScript support and a great developer experience.

## 🚀 Key Features

- **Typed GraphQL Client**: Full TypeScript support with generated types and SDK integration
- **Market Operations**: Ready-to-use methods for market data fetching
- **Flexible & Practical**: Generic query methods alongside typed convenience methods
- **Modern Architecture**: ESM-first with comprehensive error handling
- **Essential Utilities**: Curated set of the most useful helper functions

## 📦 Installation

```bash
npm install @mercnet/core graphql-request
# or
pnpm add @mercnet/core graphql-request
# or
yarn add @mercnet/core graphql-request
```

## 🎯 Quick Start

### Basic GraphQL Client Usage

```typescript
import { createGraphQLClient, type Market } from '@mercnet/core'

// Create client
const client = createGraphQLClient({
  endpoint: 'https://api.mercnet.example/graphql',
  headers: {
    'Authorization': 'Bearer your-token'
  },
  debug: true
})

// Get all markets (typed method)
const markets: Market[] = await client.getAllMarkets()
console.log(`Found ${markets.length} markets`)

// Get specific market by ID (typed method)
const market: Market | null = await client.getMarketById(123)
if (market) {
  console.log(`Market: ${market.name} - Volume: ${market.totalVolume}`)
}
```

### Using Generic Query Methods

```typescript
// For maximum flexibility
const customQuery = `
  query GetTopMarkets($limit: Int!) {
    marketCollection(first: $limit, orderBy: [{ totalVolume: DESC }]) {
      edges {
        node {
          id
          name
          totalVolume
          category
        }
      }
    }
  }
`

const result = await client.query(customQuery, { limit: 10 })
```

## 📊 Market Data Types

The library provides a clean, simplified `Market` interface:

```typescript
interface Market {
  id: string
  name: string
  description: string
  category: string
  status: string
  createdAt: Date
  updatedAt: Date
  totalVolume: string
  totalTrades: number
  isActive: boolean
  metadata?: Record<string, unknown>
}
```

## 🛠 Core API Reference

### GraphQL Client

#### Configuration

```typescript
interface GraphQLClientConfig {
  endpoint: string
  headers?: Record<string, string>
  retries?: number  // default: 3
  debug?: boolean   // default: false
}
```

#### Client Methods

```typescript
class MercNetGraphQLClient {
  // Typed market methods
  async getAllMarkets(): Promise<Market[]>
  async getMarketById(id: number): Promise<Market | null>
  
  // Generic methods for flexibility
  async query<T>(query: string, variables?: any): Promise<T>
  async mutate<T>(mutation: string, variables?: any): Promise<T>
  async rawRequest<T>(query: string, variables?: any): Promise<GraphQLResponse<T>>
  
  // Header management
  setHeader(key: string, value: string): void
  setHeaders(headers: Record<string, string>): void
}
```

### Essential Utilities

#### String Operations
```typescript
import { capitalize, camelCase } from '@mercnet/core'

capitalize('hello world')  // "Hello world"
camelCase('hello-world')   // "helloWorld"
```

#### Object Manipulation
```typescript
import { pick } from '@mercnet/core'

const user = { id: '1', name: 'John', email: 'john@example.com', password: 'secret' }
const publicData = pick(user, ['id', 'name', 'email'])
```

#### Array Utilities
```typescript
import { unique } from '@mercnet/core'

const ids = [1, 2, 2, 3, 1, 4]
const uniqueIds = unique(ids)  // [1, 2, 3, 4]
```

#### Promise Helpers
```typescript
import { sleep, retry } from '@mercnet/core'

// Wait for 1 second
await sleep(1000)

// Retry with exponential backoff
const result = await retry(
  () => fetchMarketData(),
  { retries: 3, delay: 1000, backoff: 2 }
)
```

#### Date Formatting
```typescript
import { formatDate, isValidDate } from '@mercnet/core'

formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
isValidDate(someValue)  // Type guard
```

### Error Handling

```typescript
import { MercNetError } from '@mercnet/core'

try {
  const markets = await client.getAllMarkets()
} catch (error) {
  if (error instanceof MercNetError) {
    console.log('Error code:', error.code)
    console.log('Details:', error.details)
  }
}
```

### Environment Utilities

```typescript
import { getEnv, isDevelopment, isProduction } from '@mercnet/core'

const apiUrl = getEnv('API_URL', 'https://api.mercnet.example')
if (isDevelopment()) {
  console.log('Running in development mode')
}
```

## 🔧 Advanced Usage

### Batch Operations

```typescript
async function fetchMultipleMarkets(client: MercNetGraphQLClient, ids: number[]) {
  const promises = ids.map(async id => {
    try {
      return await client.getMarketById(id)
    } catch (error) {
      console.warn(`Failed to fetch market ${id}:`, error)
      return null
    }
  })
  
  const results = await Promise.all(promises)
  return results.filter((market): market is Market => market !== null)
}
```

### Custom Headers & Authentication

```typescript
const client = createGraphQLClient({
  endpoint: 'https://api.mercnet.example/graphql'
})

// Set authentication
client.setHeader('Authorization', `Bearer ${token}`)

// Set multiple headers
client.setHeaders({
  'X-API-Version': 'v1',
  'X-Client-Version': '1.0.0'
})
```

### Error Recovery

```typescript
async function robustMarketFetch(id: number): Promise<Market | null> {
  try {
    return await client.getMarketById(id)
  } catch (error) {
    if (error instanceof MercNetError && error.code === 'GRAPHQL_ERROR') {
      // Handle GraphQL-specific errors
      return null
    }
    throw error  // Re-throw unexpected errors
  }
}
```

## 📝 GraphQL Schema Integration

The library includes generated types and queries for the MercNet GraphQL schema:

### Available Queries

1. **GetAllMarkets** - Fetches all markets from `marketCollection`
2. **GetMarketById** - Fetches a specific market by ID with filtering

### Generated Types

- `GetAllMarketsQuery`
- `GetMarketByIdQuery` 
- `GetMarketByIdQueryVariables`
- `MarketNode`, `MarketEdge`, `MarketConnection`
- `MarketFilter`, `BigIntFilter`, `StringFilter`

## 🎨 TypeScript Support

Full TypeScript support with:
- Comprehensive type definitions
- Generic type parameters
- Type guards and utilities
- Generated GraphQL types
- Strict null checks compatibility

## 🔍 Debugging

Enable debug mode to see detailed logs:

```typescript
const client = createGraphQLClient({
  endpoint: 'https://api.mercnet.example/graphql',
  debug: true  // Logs queries, variables, and responses
})
```

## 📊 Performance Considerations

- Built-in retry logic with exponential backoff
- Efficient data transformation from GraphQL edges/nodes to clean objects
- Tree-shakeable exports for minimal bundle size
- Modern ESM with optimized bundling

## 🚦 Migration from Previous Versions

This v1 represents a focused refinement:

- **Removed**: Less essential utilities to reduce complexity
- **Enhanced**: GraphQL client with typed methods
- **Added**: Generated types and SDK integration
- **Simplified**: Cleaner API surface with better TypeScript support

## 🤝 Contributing

This package is part of the MercNet monorepo. See the main repository for contribution guidelines.

## 📄 License

MIT

---

**Built with ❤️ for the MercNet ecosystem**