npm package: @groundbrick/sveltekit-adapter
Description: SvelteKit integration adapter with API client, stores, hooks, analytics, and cookie consent system
Author: Cleiton Marques
Latest version: 0.3.0

# @groundbrick/sveltekit-adapter

SvelteKit integration adapter para o microframework TypeScript - fornece integração client-side com APIs Express, gerenciamento de estado reativo, autenticação JWT, hooks e sistema de consentimento de cookies.

## Features Implementadas

- **🔧 ApiClient** - Cliente HTTP com autenticação, retry, timeout e suporte a cookies
- **🔐 Gerenciamento de Autenticação** - Autenticação segura usando HttpOnly cookies
- **📊 Stores Reativas** - Stores Svelte para estado de auth e API com suporte a runes
- **� Sistema de Notificações** - Sistema completo de notificações toast com auto-clear na navegação
- **�🛡️ Error Handling** - Hooks abrangentes de tratamento de erros
- **📝 Request Logging** - Log automático de request/response com timing
- **🎣 SvelteKit Hooks** - Hooks pré-construídos para autenticação e logging
- **🔄 Retry Logic** - Lógica de retry automática com exponential backoff
- **⏱️ Timeout Handling** - Controle de timeout configurável para requests
- **🍪 Cookie Consent** - Sistema GDPR-compliant de consentimento com Google Analytics

## Instalação

```bash
npm install @groundbrick/sveltekit-adapter
```

### Peer Dependencies

```bash
npm install @sveltejs/kit svelte
```

## Quick Start

### 1. Configuração de Hooks

```typescript
// src/hooks.server.ts
import { sequence } from '@sveltejs/kit/hooks';
import { createSvelteKitHooks } from '@groundbrick/sveltekit-adapter';

const { hooks, handleError } = createSvelteKitHooks({
  logger: {
    logRequests: true,
    logResponses: true,
    includeHeaders: false,
    excludePaths: ['/favicon.ico', '/robots.txt', '/health'],
    context: 'my-app'
  },
  auth: {
    tokenKey: 'auth_token',
    publicPaths: ['/login', '/register', '/', '/api/public/*'],
    redirectPath: '/login',
    onAuthRequired: () => {
      console.log('Authentication required');
    }
  },
  errorHandler: {
    logErrors: true,
    context: 'my-app',
    onError: (error, context) => {
      // Custom error handling
      console.error('App error:', error, context);
    }
  }
});

export const handle = sequence(...hooks);
export { handleError };
```

### 2. Configuração do API Client

```typescript
// src/lib/api.ts
import { createApiClient } from '@groundbrick/sveltekit-adapter';

export const apiClient = createApiClient({
  baseUrl: 'http://localhost:3000/api',
  timeout: 10000,
  retries: 3,
  defaultHeaders: {
    'X-App-Version': '1.0.0',
    'X-Client': 'sveltekit'
  }
});
```

### 3. Cookie Consent Setup

```typescript
// src/routes/+layout.svelte
<script lang="ts">
  import { 
    CookieConsent, 
    ConsentService,
    createConsentAwareAnalytics 
  } from '@groundbrick/sveltekit-adapter/consent';

  // Initialize consent service
  const consentService = ConsentService.getInstance();
  
  // Setup analytics with consent awareness
  const analytics = createConsentAwareAnalytics(consentService, {
    gaId: 'G-XXXXXXXXXX',
    enableDebug: true
  });
</script>

<!-- Your app content -->
<slot />

<!-- Cookie consent banner -->
<CookieConsent 
  theme="light"
  position="bottom"
  onConsentChange={(state) => {
    console.log('Consent updated:', state);
  }}
/>
```

### 4. Using Stores

```typescript
// src/routes/+page.svelte
<script lang="ts">
  import { 
    authStore, 
    apiStore, 
    isAuthenticated, 
    currentUser,
    initializeStores 
  } from '@groundbrick/sveltekit-adapter';

  // Initialize stores on app start
  initializeStores();

  // Reactive to authentication state
  $: if ($isAuthenticated) {
    console.log('User is logged in:', $currentUser);
  }
</script>

{#if $isAuthenticated}
  <h1>Welcome, {$currentUser?.name}!</h1>
{:else}
  <a href="/login">Please log in</a>
{/if}

{#if $apiStore.loading}
  <div class="spinner">Loading...</div>
{/if}

{#if $apiStore.error}
  <div class="error">{$apiStore.error}</div>
{/if}
```

## Module Exports

### Main Package

```typescript
// Everything from client and hooks
import { 
  createApiClient, 
  authStore, 
  createSvelteKitHooks 
} from '@groundbrick/sveltekit-adapter';
```

### Client Module

```typescript
// Just client functionality
import { 
  ApiClient, 
  createApiClient,
  authStore,
  apiStore,
  isAuthenticated,
  currentUser,
  isLoading,
  currentError,
  initializeStores,
  clearErrors
} from '@groundbrick/sveltekit-adapter/client';
```

### Hooks Module

```typescript
// Just hooks functionality
import { 
  createSvelteKitHooks,
  createAuthHook,
  createLoggerHook,
  createErrorHandlerHook
} from '@groundbrick/sveltekit-adapter/hooks';
```

### Consent Module

```typescript
// Cookie consent system
import { 
  CookieConsent,
  ConsentService,
  createConsentAwareAnalytics,
  GDPR_CONFIG,
  CCPA_CONFIG
} from '@groundbrick/sveltekit-adapter/consent';
```

## API Client Features

### Basic Usage

```typescript
import { createApiClient } from '@groundbrick/sveltekit-adapter';

const client = createApiClient({
  baseUrl: 'https://api.example.com',
  timeout: 10000,
  retries: 3
});

// GET request
const users = await client.get('/users');

// POST request with data
const newUser = await client.post('/users', {
  name: 'John Doe',
  email: 'john@example.com'
});

// Request with auth token
const profile = await client.get('/profile', {
  headers: { Authorization: 'Bearer token' }
});
```

### Advanced Configuration

```typescript
const client = createApiClient({
  baseUrl: 'https://api.example.com',
  timeout: 15000,
  retries: 5,
  retryDelay: 1000,
  defaultHeaders: {
    'Content-Type': 'application/json',
    'X-API-Version': '2024-01-01'
  },
  interceptors: {
    request: (config) => {
      // Add timestamp to all requests
      config.headers['X-Timestamp'] = new Date().toISOString();
      return config;
    },
    response: (response) => {
      // Log all successful responses
      console.log('Response received:', response.status);
      return response;
    },
    error: (error) => {
      // Custom error handling
      if (error.status === 401) {
        // Redirect to login
        window.location.href = '/login';
      }
      throw error;
    }
  }
});
```

### Authentication Flow

The adapter provides secure authentication using HttpOnly cookies:

#### How Authentication Works:

1. **Server-side**: Auth hook validates JWT tokens from HttpOnly cookies (no client-side token handling)
2. **Client-side**: API Client automatically includes cookies with all requests
3. **Automatic cleanup**: Invalid tokens are cleared through HttpOnly cookie management
4. **Smart redirects**: Users are redirected to login with current page as return URL
5. **No performance impact**: No unnecessary API calls on page loads

#### Auth Hook Configuration:

```typescript
// src/hooks.server.ts
const { hooks, handleError } = createSvelteKitHooks({
  auth: {
    tokenKey: 'auth_token',
    redirectPath: '/login',
    publicPaths: [
      '/login',
      '/register', 
      '/',
      '/landing',
      '/api/*', // Allow API calls to pass through
      '/favicon.ico',
      '/robots.txt'
    ],
    validateExpiration: true // Enable JWT expiration checking (default: true)
  }
});
```

## Cookie Consent System

### GDPR Compliance

```typescript
import { 
  ConsentService, 
  GDPR_CONFIG,
  createConsentAwareAnalytics 
} from '@groundbrick/sveltekit-adapter/consent';

// GDPR-compliant setup
const consentService = ConsentService.getInstance(GDPR_CONFIG);

// Analytics only loads with explicit consent
const analytics = createConsentAwareAnalytics(consentService, {
  gaId: 'G-XXXXXXXXXX',
  anonymizeIp: true
});

// Track events (respects consent automatically)
analytics.trackEvent({
  action: 'button_click',
  category: 'UI',
  label: 'signup'
});
```

### Custom Configuration

```typescript
const customConfig = {
  banner: {
    title: '🍪 Cookies',
    message: 'We use cookies to improve your experience.',
    acceptAllText: 'Accept All',
    rejectAllText: 'Reject All'
  },
  categories: {
    functional: {
      required: true,
      name: 'Essential',
      description: 'Required for basic functionality'
    },
    analytics: {
      required: false,
      name: 'Analytics',
      description: 'Help us improve our website'
    }
  }
};

const consentService = ConsentService.getInstance(customConfig);
```

## Stores System

### Authentication Store

```typescript
import { authStore, isAuthenticated, currentUser } from '@groundbrick/sveltekit-adapter';

// Reactive authentication state
$: if ($isAuthenticated) {
  console.log('User:', $currentUser);
}

// Login
authStore.login({
  token: 'jwt-token',
  user: { id: 1, name: 'John', email: 'john@example.com' }
});

// Logout
authStore.logout();

// Check if user has specific role
if ($currentUser?.roles?.includes('admin')) {
  // Show admin content
}
```

### API Store

```typescript
import { apiStore, isLoading, currentError } from '@groundbrick/sveltekit-adapter';

// Loading states
$: if ($isLoading) {
  // Show spinner
}

// Error handling
$: if ($currentError) {
  // Show error message
  console.error('API Error:', $currentError);
}

// Manual error clearing
apiStore.clearError();
```

### Notification System

```typescript
import { 
  showSuccess, 
  showError, 
  showWarning, 
  showInfo,
  clearAllNotifications,
  useNavigationNotificationClear 
} from '@groundbrick/sveltekit-adapter';

// Enable auto-clearing on navigation (add to your root layout)
useNavigationNotificationClear();

// Show different types of notifications
showSuccess('Data saved successfully!');
showError('Something went wrong!');
showWarning('This action cannot be undone!');
showInfo('New feature available!');

// With options
showSuccess('Operation complete!', {
  title: 'Success',
  duration: 3000,
  persistent: false // won't clear on navigation if true
});

// Clear notifications
clearAllNotifications();
```

Add notification component to your layout:

```svelte
<script>
  import { useNavigationNotificationClear } from '@groundbrick/sveltekit-adapter';
  import Notifications from '$lib/components/Notifications.svelte';
  
  // Enable auto-clearing
  useNavigationNotificationClear();
</script>

<main>
  <slot />
</main>

<!-- Notifications -->
<Notifications />
```

### Logging Estruturado

- **Request/Response**: Log automático com timing
```typescript
// Configuração no hooks.server.ts
const loggerHook = createLoggerHook({
  logRequests: true,   // GET /api/users [timing: 245ms]
  logResponses: true   // GET /api/users 200 OK [duration: 245ms]
});

// Logs automáticos no console/arquivo
// INFO: Incoming request { method: 'GET', url: '/api/users', duration: 245 }
```

- **Context preservation**: Mantém contexto através da aplicação
```typescript
// Contexto propagado automaticamente
const logger = createLogger().child('user-service');
// user-service: Processing user creation
// user-service: Database query completed
// user-service: User created successfully
```

- **Structured data**: Logs estruturados com metadados
```typescript
// Metadados automáticos em cada log
logger.info('User login', {
  userId: 123,
  ip: '192.168.1.1',
  userAgent: 'Chrome/120.0',
  timestamp: '2024-01-15T10:30:00Z',
  requestId: 'req_abc123'
});
```

- **Performance tracking**: Tracking de performance automático
```typescript
// Timing automático de requests
const startTime = Date.now();
await apiClient.get('/heavy-endpoint');
// Log: Request completed { duration: 1247ms, status: 200 }

// Timing de hooks
// Log: Request processed { url: '/dashboard', duration: 89ms }
```

## Melhores Práticas

1. **Inicialize stores cedo** no ciclo de vida da aplicação
2. **Use stores reativas** em vez de gerenciamento manual de estado
3. **Configure hooks apropriadamente** para as necessidades da sua aplicação
4. **Use TypeScript** para melhor experiência de desenvolvimento
5. **Trate erros graciosamente** com os error stores
6. **Configure paths públicos** no hook de autenticação
7. **Use retry mechanism** para endpoints instáveis
8. **Implemente consent** desde o início para compliance
9. **Configure analytics** com consent awareness
10. **Use presets** de configuração para diferentes regiões

## Compatibilidade

- **Svelte 5.x** com runes support
- **SvelteKit 2.x** com app directory structure
- **Node.js 18+** para funcionalidades de servidor
- **TypeScript 5.x** para tipagem completa

## Dependencies

### Required
- `@groundbrick/logger` - Sistema de logging

### Peer Dependencies  
- `@sveltejs/kit` - SvelteKit framework (^2.0.0)
- `svelte` - Svelte framework (^5.0.0)

## License

MIT

## Packaging & build notes

- During the package build we copy some source assets (for example, `.svelte` components) from `src/` into the published `dist/` folder. This is handled by the script `scripts/copy-assets.js` which runs after `tsc` in the package `build` script.

- Why: some modules are intentionally re-exported as source Svelte components (for example `analytics/components/GoogleAnalytics.svelte`). The compiled TypeScript output in `dist` contains runtime imports to those `.svelte` files. To make the package consumable by apps that will compile Svelte components in their own build (SvelteKit apps), we ship the `.svelte` files alongside the compiled JS so imports resolve correctly.

- Why not rsync: earlier we used `rsync` to copy files, but that requires `rsync` to be present on the build server. To make builds portable across environments we now use a small cross-platform Node script.

- Alternatives:
  - Precompile Svelte components into JavaScript during the package build (using Rollup/Vite or `svelte/compiler`). This produces a distribution with JS only (no `.svelte` sources), which is cleaner for non-Svelte consumers but requires adding a Svelte compilation step to the package build.
  - Keep shipping `.svelte` files (the current approach). This is the simplest and lets SvelteKit apps compile components during app build time.

- If you prefer a precompiled distribution, open an issue or request and we can add a Rollup/Vite build step (low-risk, slightly larger change).