@salla.sa/ecommerce-events-base
Version:
Base types and utilities for Salla ecommerce event tracking
292 lines (224 loc) ⢠8.47 kB
Markdown
# @salla.sa/ecommerce-events-base
A comprehensive TypeScript package providing type-safe ecommerce event tracking with automatic listener discovery for Salla applications.
## š Features
- **Complete TypeScript Types**: Full type definitions for Segment Ecommerce v2 events
- **Auto-Discovery Plugin**: Vite plugin that automatically discovers and registers event listeners
- **Type-Safe Interface**: Strongly typed interface for Salla analytics tracker
- **Browser & Node.js Support**: Dual exports for different environments
- **Zero Configuration**: Works out of the box with conventional file structure
## š¦ Installation
```bash
npm install @salla.sa/ecommerce-events-base
```
## šļø Quick Start
### 1. Install and Configure Vite Plugin
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import { AutoRegistryEventsPlugin } from '@salla.sa/ecommerce-events-base/plugin';
export default defineConfig({
plugins: [
AutoRegistryEventsPlugin()
]
});
```
### 2. Create Event Listeners
Create listeners in your `src/listeners/` directory following this pattern:
```typescript
// src/listeners/product-viewed.ts
import { ProductViewedPayload, EcommerceEvents } from '@salla.sa/ecommerce-events-base';
export const eventName = EcommerceEvents.PRODUCT_VIEWED;
export default (payload: ProductViewedPayload): void => {
console.log('Product viewed:', payload);
// Your custom tracking logic here
// e.g., send to analytics service
};
```
### 3. Use Types in Your Application
```typescript
import {
Product,
Order,
EcommerceEvents,
ProductViewedPayload,
SallaTracker
} from '@salla.sa/ecommerce-events-base';
// Type-safe product definition
const product: Product = {
product_id: '123',
name: 'Sample Product',
price: 29.99,
category: 'Electronics'
};
// Type-safe tracker implementation
const tracker: SallaTracker = {
name: 'my-custom-tracker',
track: (eventName: string, payload: any) => {
console.log(`Tracking ${eventName}:`, payload);
}
};
```
## š§ Auto-Discovery Plugin
The [`AutoRegistryEventsPlugin`](src/ecommerce-event-discover.ts) automatically:
- **Discovers** event listeners in `src/listeners/` directory
- **Generates** an auto-registry file mapping events to handlers
- **Supports** both development and build modes
- **Validates** listener file patterns for consistency
### How It Works
1. **Scans** your `src/listeners/` directory for `.ts` files
2. **Parses** each file to extract `eventName` and default export
3. **Generates** `src/auto-listeners-registry.ts` with all mappings
4. **Registers** listeners automatically during build/dev
### Expected Listener Pattern
```typescript
// src/listeners/[event-name].ts
import { [PayloadType], EcommerceEvents } from '@salla.sa/ecommerce-events-base';
// Required: Export the event name
export const eventName = EcommerceEvents.[EVENT_NAME];
// Required: Default export function with typed payload
export default (payload: [PayloadType]): void => {
// Your event handling logic
};
```
## š Available Types
### Core Interfaces
| Interface | Description |
|-----------|-------------|
| [`Product`](src/types/segment-ecommerce.ts:2) | Product information structure |
| [`Cart`](src/types/segment-ecommerce.ts:17) | Shopping cart structure |
| [`Order`](src/types/segment-ecommerce.ts:22) | Order information structure |
| [`Checkout`](src/types/segment-ecommerce.ts:35) | Checkout process structure |
| [`Promotion`](src/types/segment-ecommerce.ts:51) | Promotion/discount structure |
### Event Payload Types
| Payload Type | Event | Description |
|--------------|-------|-------------|
| [`ProductViewedPayload`](src/types/segment-ecommerce.ts:59) | Product Viewed | When a product is viewed |
| [`ProductAddedPayload`](src/types/segment-ecommerce.ts:82) | Product Added | When a product is added to cart |
| [`CartViewedPayload`](src/types/segment-ecommerce.ts:114) | Cart Viewed | When cart is viewed |
| [`CheckoutStartedPayload`](src/types/segment-ecommerce.ts:119) | Checkout Started | When checkout process begins |
| [`OrderCompletedPayload`](src/types/segment-ecommerce.ts:154) | Order Completed | When an order is completed |
| [`CouponAppliedPayload`](src/types/segment-ecommerce.ts:248) | Coupon Applied | When a coupon is applied |
| [`WishlistProductAddedPayload`](src/types/segment-ecommerce.ts:272) | Wishlist Product Added | When product added to wishlist |
### Enums
| Enum | Description |
|------|-------------|
| [`EcommerceEvents`](src/types/segment-ecommerce.ts:332) | All supported event names |
### Tracker Interface
```typescript
interface SallaTracker {
name: string;
track: (eventName: string, payload: EcommerceEventPayload) => void;
page?: (payload: any) => void;
}
```
## šÆ Usage Examples
### Basic Event Listener
```typescript
// src/listeners/order-completed.ts
import { OrderCompletedPayload, EcommerceEvents } from '@salla.sa/ecommerce-events-base';
export const eventName = EcommerceEvents.ORDER_COMPLETED;
export default (payload: OrderCompletedPayload): void => {
// Send to analytics
gtag('event', 'purchase', {
transaction_id: payload.order_id,
value: payload.total,
currency: payload.currency,
items: payload.products.map(product => ({
item_id: product.product_id,
item_name: product.name,
category: product.category,
quantity: product.quantity,
price: product.price
}))
});
};
```
### Advanced Listener with Multiple Services
```typescript
// src/listeners/product-added.ts
import { ProductAddedPayload, EcommerceEvents } from '@salla.sa/ecommerce-events-base';
export const eventName = EcommerceEvents.PRODUCT_ADDED;
export default (payload: ProductAddedPayload): void => {
// Multiple tracking services
// Google Analytics
gtag('event', 'add_to_cart', {
currency: 'SAR',
value: payload.price * (payload.quantity || 1),
items: [{
item_id: payload.product_id,
item_name: payload.name,
category: payload.category,
quantity: payload.quantity || 1,
price: payload.price
}]
});
// Facebook Pixel
fbq('track', 'AddToCart', {
content_ids: [payload.product_id],
content_type: 'product',
value: payload.price,
currency: 'SAR'
});
// Custom API
fetch('/api/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event: 'product_added',
payload
})
});
};
```
## š Plugin Configuration
The plugin works with zero configuration, but you can customize its behavior:
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import { AutoRegistryEventsPlugin } from '@salla.sa/ecommerce-events-base/plugin';
export default defineConfig({
plugins: [
AutoRegistryEventsPlugin({
// Plugin automatically discovers listeners in src/listeners/
// No configuration needed for standard setups
})
]
});
```
## š Project Structure
```
your-project/
āāā src/
ā āāā listeners/ # Event listeners directory
ā ā āāā product-viewed.ts
ā ā āāā cart-viewed.ts
ā ā āāā order-completed.ts
ā ā āāā ...
ā āāā auto-listeners-registry.ts # Auto-generated (don't edit)
ā āāā index.ts
āāā vite.config.ts # Vite configuration
āāā package.json
```
## š¦ Development Workflow
1. **Install** the package and configure the Vite plugin
2. **Create** event listeners in `src/listeners/` following the pattern
3. **Run** your development server - plugin auto-generates registry
4. **Build** your project - registry is included in the build
5. **Deploy** - all listeners are automatically registered
## š§ Troubleshooting
### Plugin Not Discovering Listeners
Ensure your listeners follow the exact pattern:
- Located in `src/listeners/` directory
- Export `eventName` from `EcommerceEvents` enum
- Export default function with typed payload
### TypeScript Errors
Make sure you're importing types correctly:
```typescript
import { EcommerceEvents, ProductViewedPayload } from '@salla.sa/ecommerce-events-base';
```
### Build Issues
The plugin requires Node.js environment for file system operations. It's automatically excluded from browser builds.
## š License
MIT Ā© [Salla](https://github.com/SallaApp)
## š¤ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.