npm package: @fuyabe/izmir-sdk
Description: Izmir SDK for tracking ad events with React support
Latest version: 2.0.0

# Izmir SDK

Izmir SDK, reklam takibi ve analitik verileri toplamak için geliştirilmiş modern, güvenli ve React-friendly bir JavaScript SDK'dır.

## 🚀 Özellikler

- 🔒 **Güvenlik Odaklı** - Input validation, error handling ve retry mechanism
- ⚛️ **React Hooks** - Modern React projeler için özel hook'lar
- 🌐 **SSR Uyumlu** - Server-side rendering desteği
- 📱 **TypeScript** - Tam TypeScript desteği
- 🔄 **Retry Mechanism** - Otomatik yeniden deneme sistemi
- 📊 **Auto-tracking** - Otomatik impression ve hover tracking
- 🎯 **Minimal Bundle** - Optimize edilmiş paket boyutu

## 📦 Kurulum

```bash
# Bun ile (önerilen)
bun add @fuyabe/izmir-sdk

# NPM ile
npm install @fuyabe/izmir-sdk

# Yarn ile
yarn add @fuyabe/izmir-sdk
```

## 🔧 Temel Kullanım

### Vanilla JavaScript

```javascript
import { Izmir } from '@fuyabe/izmir-sdk';

// SDK'yi başlat
const izmir = new Izmir({
    endpoint: 'https://api.example.com',
    siteId: 123,
    userId: 'user-456', // opsiyonel
    retryAttempts: 3,    // opsiyonel, varsayılan: 3
    timeout: 5000        // opsiyonel, varsayılan: 5000ms
});

// Event tracking
async function trackAdClick() {
    const result = await izmir.track('click', 'ad-123');
    if (result.success) {
        console.log('Event başarıyla gönderildi');
    } else {
        console.error('Hata:', result.error);
    }
}

// IP adresini yenile
const currentIP = await izmir.refreshIP();
console.log('Mevcut IP:', currentIP);
```

### React Hooks ile Kullanım

#### 1. Temel Hook Kullanımı

```jsx
import { useIzmir } from '@fuyabe/izmir-sdk';

function MyComponent() {
    const { track, isInitialized, error } = useIzmir({
        endpoint: 'https://api.example.com',
        siteId: 123,
        userId: 'user-456'
    });

    const handleAdClick = async (adId) => {
        const result = await track('click', adId);
        console.log('Tracking sonucu:', result);
    };

    if (error) {
        return <div>SDK Hatası: {error}</div>;
    }

    if (!isInitialized) {
        return <div>SDK yükleniyor...</div>;
    }

    return (
        <button onClick={() => handleAdClick('ad-123')}>
            Reklam
        </button>
    );
}
```

#### 2. Spesifik Tracking Hook'u

```jsx
import { useAdClickTracker } from '@fuyabe/izmir-sdk';

function AdComponent({ adId }) {
    const { trackClick, trackImpression, trackHover } = useAdClickTracker({
        endpoint: 'https://api.example.com',
        siteId: 123
    });

    return (
        <div 
            onMouseEnter={() => trackHover(adId)}
            onClick={() => trackClick(adId)}
            onLoad={() => trackImpression(adId)}
        >
            Reklam İçeriği
        </div>
    );
}
```

#### 3. Otomatik Tracking Hook'u

```jsx
import { useAdAutoTracker } from '@fuyabe/izmir-sdk';
import { useRef, useEffect } from 'react';

function AutoTrackedAd({ adId }) {
    const adRef = useRef();
    const { trackElement } = useAdAutoTracker({
        endpoint: 'https://api.example.com',
        siteId: 123
    }, {
        trackImpressions: true,
        trackHovers: true,
        impressionThreshold: 0.7 // %70 görünür olduğunda impression say
    });

    useEffect(() => {
        if (adRef.current) {
            // Element'i tracking'e kaydet, cleanup function'ı döner
            const cleanup = trackElement(adRef.current, adId);
            return cleanup;
        }
    }, [adId, trackElement]);

    return (
        <div ref={adRef} className="ad-container">
            {/* Reklam içeriği otomatik olarak track edilir */}
            <img src="/ad-banner.jpg" alt="Reklam" />
        </div>
    );
}
```

## 🛠️ API Fonksiyonları

SDK ayrıca reklam verilerini almak için API fonksiyonları sağlar:

```javascript
import { 
    getAdWithId, 
    getAdsWithSiteId, 
    getSiteWithDomain,
    getMultipleAds 
} from '@fuyabe/izmir-sdk';

// Tekil reklam getir
const ad = await getAdWithId('https://api.example.com', 123);

// Site'a ait reklamları getir
const ads = await getAdsWithSiteId('https://api.example.com', 456);

// Domain'e ait site bilgisi
const site = await getSiteWithDomain('https://api.example.com', 'example.com');

// Toplu reklam getir (yeni özellik)
const multipleAds = await getMultipleAds('https://api.example.com', [1, 2, 3]);

// Config ile timeout ve retry ayarları
const adWithConfig = await getAdWithId(
    'https://api.example.com', 
    123, 
    { timeout: 3000, retryAttempts: 2 }
);
```

## 🔒 Güvenlik Özellikleri

### Input Validation
```javascript
// Tüm fonksiyonlarda otomatik validation
const izmir = new Izmir({
    endpoint: 'https://api.example.com', // ✅ Geçerli URL olmalı
    siteId: 123,                         // ✅ Pozitif integer olmalı
    userId: 'user-456'                   // ✅ String olmalı
});

// Hatalı kullanımda exception fırlatır
try {
    await izmir.track('invalid-type', ''); // ❌ Error
} catch (error) {
    console.error(error.message);
}
```

### Rate Limiting & Retry
```javascript
// Otomatik retry mechanism
const izmir = new Izmir({
    endpoint: 'https://api.example.com',
    siteId: 123,
    retryAttempts: 5,    // 5 kez dene
    timeout: 10000       // 10 saniye timeout
});

// Exponential backoff ile yeniden deneme
// 1. deneme: hemen
// 2. deneme: 1 saniye sonra  
// 3. deneme: 2 saniye sonra
// 4. deneme: 4 saniye sonra
// 5. deneme: 5 saniye sonra (max)
```

## 🌐 SSR (Server-Side Rendering) Desteği

```javascript
// Next.js veya diğer SSR framework'ler için güvenli
import { useIzmir } from '@fuyabe/izmir-sdk';

function MyPage() {
    const { track, isInitialized } = useIzmir({
        endpoint: 'https://api.example.com',
        siteId: 123
    });

    // Server-side'da çalışmaz, sadece client-side'da aktif olur
    // localStorage ve IP detection browser'da çalışır
    
    return <div>...</div>;
}
```

## 📊 Event Types

SDK üç tür event tracking destekler:

- **click**: Kullanıcı reklama tıkladığında
- **impression**: Reklam görüntülendiğinde  
- **hover**: Kullanıcı reklamın üzerine geldiğinde

```javascript
await izmir.track('click', 'ad-123');
await izmir.track('impression', 'ad-123');
await izmir.track('hover', 'ad-123');
```

## 🔧 Konfigürasyon Seçenekleri

| Seçenek | Tip | Varsayılan | Açıklama |
|---------|-----|------------|----------|
| `endpoint` | string | - | **Gerekli.** API endpoint URL'i |
| `siteId` | number | - | **Gerekli.** Site ID'si |
| `userId` | string | "anonymous" | Opsiyonel. Kullanıcı ID'si |
| `retryAttempts` | number | 3 | Başarısız isteklerde deneme sayısı |
| `timeout` | number | 5000 | İstek timeout süresi (ms) |

## 📈 Gelişmiş Örnekler

### E-commerce Tracking
```jsx
function ProductAd({ productId, adId }) {
    const { trackClick, trackImpression } = useAdClickTracker({
        endpoint: 'https://api.mystore.com',
        siteId: 100
    });

    useEffect(() => {
        // Ürün görüntülendiğinde impression track et
        trackImpression(adId);
    }, []);

    const handlePurchase = () => {
        // Satın alma tıklamasını track et
        trackClick(adId);
        // E-commerce tracking logic...
    };

    return (
        <div className="product-ad">
            <img src={`/products/${productId}.jpg`} />
            <button onClick={handlePurchase}>
                Satın Al
            </button>
        </div>
    );
}
```

### Dashboard Analytics
```jsx
function AnalyticsDashboard() {
    const [stats, setStats] = useState(null);
    
    const { getConfig, refreshIP } = useIzmir({
        endpoint: 'https://api.example.com',
        siteId: 123
    });

    const checkCurrentStatus = async () => {
        const config = getConfig();
        const currentIP = await refreshIP();
        
        setStats({
            endpoint: config.endpoint,
            siteId: config.siteId,
            currentIP: currentIP,
            lastUpdated: new Date()
        });
    };

    return (
        <div>
            <h2>SDK Status</h2>
            <button onClick={checkCurrentStatus}>
                Durumu Güncelle
            </button>
            {stats && (
                <pre>{JSON.stringify(stats, null, 2)}</pre>
            )}
        </div>
    );
}
```

## 🐛 Hata Yönetimi

```javascript
import { ApiError } from '@fuyabe/izmir-sdk';

try {
    const result = await izmir.track('click', 'ad-123');
    if (!result.success) {
        console.log('Tracking başarısız:', result.error);
    }
} catch (error) {
    if (error instanceof ApiError) {
        console.log('API Hatası:', error.message, 'Status:', error.status);
    } else {
        console.log('Genel hata:', error.message);
    }
}
```

## 📄 Lisans

MIT

## 🤝 Katkıda Bulunma

1. Fork yapın
2. Feature branch oluşturun (`git checkout -b feature/amazing-feature`)
3. Commit yapın (`git commit -m 'Add amazing feature'`)
4. Push yapın (`git push origin feature/amazing-feature`)
5. Pull Request açın

## 📦 GitHub Packages'e Yükleme

Bu paket GitHub Packages'e private olarak yüklenmektedir.

### Otomatik Publish (GitHub Actions)
```bash
# Tag ile release oluştur
git tag v1.0.0
git push origin v1.0.0

# Veya GitHub'da release oluştur
# Actions otomatik çalışacak
```

### Manual Publish
```bash
# 1. GitHub Personal Access Token oluştur (write:packages yetkisi ile)
export GITHUB_TOKEN=your_token_here

# 2. Publish script'ini çalıştır
./scripts/publish.sh

# Veya adım adım:
bun run build
npm publish
```

### Paketi Kullanma
```bash
# .npmrc dosyasını proje köküne ekle
echo "@fuyabe:registry=https://npm.pkg.github.com" >> .npmrc

# GitHub token ile authenticate ol
npm login --scope=@fuyabe --registry=https://npm.pkg.github.com

# Paketi yükle
npm install @fuyabe/izmir-sdk
```

## 📞 Destek

Herhangi bir sorun için [GitHub Issues](https://github.com/fuyabe/izmir-sdk/issues) açabilirsiniz.