Evently

pub package License: MIT

A production-ready Flutter SDK for event tracking and analytics with clean architecture, automatic batching, offline support, and robust error handling.

โœจ Features

  • ๐Ÿ—๏ธ Clean Architecture - Separation of concerns with clear layer boundaries
  • ๐Ÿ“ฆ Automatic Batching - Efficiently groups events to reduce network requests
  • ๐Ÿ’พ Offline Queue - Stores events locally when network is unavailable
  • ๐Ÿ”„ Retry Logic - Exponential backoff for failed requests
  • ๐Ÿ›ก๏ธ Error Handling - Comprehensive error handling with custom exceptions
  • ๐Ÿ“ Structured Logging - Configurable logging for debugging
  • ๐Ÿ” Security - API key support and input validation
  • ๐Ÿงช Fully Tested - Comprehensive test coverage
  • ๐ŸŽฏ Type Safe - Strong typing with clear contracts

๐Ÿ“ฆ Installation

Add this to your package's pubspec.yaml file:

dependencies:
  evently: ^2.0.0

Then run:

flutter pub get

๐Ÿš€ Quick Start

1. Initialize the SDK

Initialize Evently in your main.dart before running your app:

import 'package:flutter/material.dart';
import 'package:evently/evently.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await EventlyClient.initialize(
    config: EventlyConfig(
      serverUrl: 'https://analytics.example.com/api',
      apiKey: 'your-api-key',
      environment: 'production',
      debugMode: false,
    ),
  );

  runApp(MyApp());
}

2. Track Events

Log events anywhere in your app:

// Simple event
await EventlyClient.instance.logEvent(
  name: 'button_click',
  screenName: 'HomeScreen',
);

// Event with properties
await EventlyClient.instance.logEvent(
  name: 'purchase_completed',
  screenName: 'CheckoutScreen',
  properties: {
    'product_id': '12345',
    'amount': 99.99,
    'currency': 'USD',
  },
  userId: 'user_123',
);

โš™๏ธ Configuration

EventlyConfig supports the following options:

EventlyConfig(
  serverUrl: 'https://api.example.com',      // Required: Your analytics server
  apiKey: 'your-api-key',                     // Optional: API authentication
  environment: 'production',                  // Environment name
  debugMode: false,                           // Enable debug logging
  batchSize: 10,                              // Events per batch
  batchIntervalSeconds: 30,                   // Max time before sending batch
  maxRetries: 3,                              // Retry attempts for failed requests
  retryDelayMs: 1000,                         // Initial retry delay
  maxOfflineEvents: 1000,                     // Max events in offline queue
  enableOfflineQueue: true,                   // Store events when offline
  requestTimeoutSeconds: 30,                  // Network timeout
)

๐Ÿ”ง Advanced Usage

Manual Flush

Force immediate sending of all batched events:

await EventlyClient.instance.flush();

Check Pending Events

Get the count of events waiting in the offline queue:

final count = await EventlyClient.instance.getPendingEventCount();
print('Pending events: $count');

Clear Offline Queue

Remove all stored offline events:

await EventlyClient.instance.clearPendingEvents();

Custom Logger

Provide your own logger implementation:

class CustomLogger implements EventlyLogger {
  @override
  void log(LogLevel level, String message, [dynamic error, StackTrace? stackTrace]) {
    // Your custom logging logic
  }
  
  // Implement other methods...
}

await EventlyClient.initialize(
  config: config,
  logger: CustomLogger(),
);

๐Ÿ—๏ธ Architecture

Evently follows Clean Architecture principles:

๐Ÿ“ lib/
โ”œโ”€โ”€ ๐Ÿ“ core/              # Core infrastructure
โ”‚   โ”œโ”€โ”€ config/           # Configuration
โ”‚   โ”œโ”€โ”€ error/            # Exceptions & failures
โ”‚   โ””โ”€โ”€ logging/          # Logging abstraction
โ”œโ”€โ”€ ๐Ÿ“ domain/            # Business logic
โ”‚   โ”œโ”€โ”€ entities/         # Core entities
โ”‚   โ””โ”€โ”€ repositories/     # Repository contracts
โ””โ”€โ”€ ๐Ÿ“ data/              # Data layer
    โ”œโ”€โ”€ models/           # Data models
    โ”œโ”€โ”€ datasources/      # Remote & local data sources
    โ””โ”€โ”€ repositories/     # Repository implementations

๐Ÿ”’ Security Best Practices

  1. Never hardcode API keys - Use environment variables or secure storage
  2. Use HTTPS - Always use secure connections for your server URL
  3. Validate input - The SDK validates all events automatically
  4. Sanitize PII - Don't include sensitive personal information in events

๐Ÿงช Testing

Run tests:

flutter test

The SDK includes comprehensive tests for:

  • Configuration validation
  • Event creation and validation
  • Client initialization
  • Error handling
  • Logging

๐Ÿ“š Example

See the example directory for a complete demo app showing all features.

๐Ÿ”„ Migration from v1.x

v2.0.0 is a breaking change with a complete rewrite. Key differences:

Old (v1.x):

Evently().initialize(serverUrl: 'https://api.example.com');
Evently().logEvent('event', screenName: 'Screen', description: 'Desc');

New (v2.0.0):

await EventlyClient.initialize(
  config: EventlyConfig(serverUrl: 'https://api.example.com'),
);
await EventlyClient.instance.logEvent(
  name: 'event',
  screenName: 'Screen',
  properties: {'description': 'Desc'},
);

Benefits of v2:

  • Async initialization for better performance
  • Configuration object for better organization
  • Properties map instead of simple description
  • Error handling with exceptions
  • Offline support and batching
  • Production-ready architecture

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

๐Ÿ“ž Support

For issues, feature requests, or questions, please file an issue on the GitHub repository.


Made with โค๏ธ by the Evently team

Libraries

evently
Evently - A production-ready Flutter SDK for event tracking and analytics.