@toyef/arise-node
v0.3.3
Published
A comprehensive Node.js analytics SDK for tracking events, page views, and user interactions in server-side applications, APIs, and backend services.
Readme
@toyef/arise-node
A comprehensive Node.js analytics SDK for tracking events, page views, and user interactions in server-side applications, APIs, and backend services.
Installation
npm install @toyef/arise-nodeQuick Start
1. Basic Setup
const { AriseServerAnalytics } = require('@toyef/arise-node');
// Initialize with your project ID
const arise = new AriseServerAnalytics('your-project-id');
// Or with configuration object
const arise = new AriseServerAnalytics({
projectId: 'your-project-id',
apiEndpoint: 'https://api.ariseapp.com', // optional
timeout: 5000, // optional
retryAttempts: 3 // optional
});2. Track Events
// Track a server-side event
await arise.trackEvent({
userId: 'user123',
eventName: 'api_request',
properties: {
endpoint: '/api/users',
method: 'GET',
response_time: 150,
status_code: 200
}
});3. Track Page Views (SSR)
// Track server-rendered page views
await arise.trackPageView({
userId: 'user123',
url: '/products/123',
title: 'Product Details - My Store',
referrer: 'https://google.com'
});4. Identify Users
// Set user traits
await arise.setUserTraits({
userId: 'user123',
traits: {
email: '[email protected]',
plan: 'premium',
signup_date: '2024-01-15',
company: 'Acme Corp'
}
});Framework Integration Examples
Express.js
const express = require('express');
const { AriseServerAnalytics } = require('@toyef/arise-node');
const app = express();
const arise = new AriseServerAnalytics(process.env.ARISE_PROJECT_ID);
// Middleware to track all requests
app.use(async (req, res, next) => {
const startTime = Date.now();
res.on('finish', async () => {
const duration = Date.now() - startTime;
await arise.trackEvent({
userId: req.user?.id || 'anonymous',
eventName: 'api_request',
properties: {
method: req.method,
url: req.originalUrl,
status_code: res.statusCode,
response_time: duration,
user_agent: req.get('User-Agent'),
ip_address: req.ip
}
});
});
next();
});
// Track user registration
app.post('/api/register', async (req, res) => {
try {
const user = await createUser(req.body);
// Track registration event
await arise.trackEvent({
userId: user.id,
eventName: 'user_registered',
properties: {
registration_method: 'email',
source: req.body.source || 'direct'
}
});
// Set user traits
await arise.setUserTraits({
userId: user.id,
traits: {
email: user.email,
name: user.name,
created_at: user.createdAt
}
});
res.json({ success: true, user });
} catch (error) {
await arise.trackEvent({
userId: 'anonymous',
eventName: 'registration_failed',
properties: {
error: error.message,
email: req.body.email
}
});
res.status(400).json({ error: error.message });
}
});
app.listen(3000);Next.js API Routes
// pages/api/analytics.js
import { AriseServerAnalytics } from '@toyef/arise-node';
const arise = new AriseServerAnalytics(process.env.ARISE_PROJECT_ID);
export default async function handler(req, res) {
if (req.method === 'POST') {
const { userId, event, properties } = req.body;
try {
await arise.trackEvent({
userId,
eventName: event,
properties: {
...properties,
timestamp: new Date(),
source: 'web_app'
}
});
res.status(200).json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}Fastify
const fastify = require('fastify')({ logger: true });
const { AriseServerAnalytics } = require('@toyef/arise-node');
const arise = new AriseServerAnalytics(process.env.ARISE_PROJECT_ID);
// Plugin for analytics
fastify.register(async function (fastify) {
fastify.addHook('onResponse', async (request, reply) => {
await arise.trackEvent({
userId: request.user?.id || 'anonymous',
eventName: 'api_request',
properties: {
method: request.method,
url: request.url,
status_code: reply.statusCode,
response_time: reply.getResponseTime()
}
});
});
});
// Routes
fastify.post('/api/events', async (request, reply) => {
const { userId, event, properties } = request.body;
await arise.trackEvent({
userId,
eventName: event,
properties
});
return { success: true };
});
const start = async () => {
try {
await fastify.listen({ port: 3000 });
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();Advanced Usage
Batch Event Tracking
const events = [
{
userId: 'user1',
type: 'event',
data: {
name: 'purchase_completed',
properties: { amount: 99.99, currency: 'USD' }
}
},
{
userId: 'user2',
type: 'pageview',
data: {
url: '/products',
title: 'Products Page'
}
}
];
// Process multiple events efficiently
const results = await arise.batchTrack(events);
console.log('Batch tracking results:', results);Session Management
// Start tracking a user session
const sessionId = 'session_' + Date.now();
await arise.trackEvent({
userId: 'user123',
eventName: 'session_started',
sessionId,
properties: {
platform: 'web',
device: 'desktop'
}
});
// Track events within the session
await arise.trackEvent({
userId: 'user123',
eventName: 'page_viewed',
sessionId,
properties: {
page: '/dashboard'
}
});
// End the session
await arise.endUserSession({
userId: 'user123',
sessionId,
duration: 1800000, // 30 minutes in milliseconds
exitPage: '/logout'
});Error Tracking
// Global error handler
process.on('uncaughtException', async (error) => {
await arise.trackEvent({
userId: 'system',
eventName: 'uncaught_exception',
properties: {
error_message: error.message,
error_stack: error.stack,
timestamp: new Date().toISOString()
}
});
process.exit(1);
});
// Express error middleware
app.use(async (err, req, res, next) => {
await arise.trackEvent({
userId: req.user?.id || 'anonymous',
eventName: 'server_error',
properties: {
error_message: err.message,
error_stack: err.stack,
url: req.originalUrl,
method: req.method,
status_code: 500
}
});
res.status(500).json({ error: 'Internal Server Error' });
});Database Event Tracking
// Track database operations
const trackDatabaseOperation = async (operation, table, userId, metadata = {}) => {
await arise.trackEvent({
userId: userId || 'system',
eventName: 'database_operation',
properties: {
operation, // 'create', 'read', 'update', 'delete'
table,
timestamp: new Date(),
...metadata
}
});
};
// Usage with Mongoose
userSchema.post('save', async function() {
await trackDatabaseOperation('create', 'users', this._id, {
email: this.email,
role: this.role
});
});
// Usage with Sequelize
User.afterCreate(async (user) => {
await trackDatabaseOperation('create', 'users', user.id, {
email: user.email,
source: user.registrationSource
});
});Background Job Tracking
// Track background job processing
const processJob = async (jobData) => {
const startTime = Date.now();
try {
await arise.trackEvent({
userId: jobData.userId || 'system',
eventName: 'job_started',
properties: {
job_type: jobData.type,
job_id: jobData.id,
priority: jobData.priority
}
});
// Process the job
const result = await executeJob(jobData);
await arise.trackEvent({
userId: jobData.userId || 'system',
eventName: 'job_completed',
properties: {
job_type: jobData.type,
job_id: jobData.id,
duration: Date.now() - startTime,
success: true,
result_size: JSON.stringify(result).length
}
});
return result;
} catch (error) {
await arise.trackEvent({
userId: jobData.userId || 'system',
eventName: 'job_failed',
properties: {
job_type: jobData.type,
job_id: jobData.id,
duration: Date.now() - startTime,
error_message: error.message
}
});
throw error;
}
};API Reference
new AriseServerAnalytics(config)
Create a new Arise analytics instance.
Parameters:
config(string | AriseConfig): Project ID string or configuration object
trackEvent(params)
Track a custom event.
Parameters:
params.userId(string): User identifierparams.eventName(string): Event nameparams.properties(object, optional): Event propertiesparams.sessionId(string, optional): Session identifierparams.timestamp(Date, optional): Event timestamp
trackPageView(params)
Track a page view (useful for SSR applications).
Parameters:
params.userId(string): User identifierparams.url(string): Page URLparams.title(string, optional): Page titleparams.referrer(string, optional): Referrer URLparams.sessionId(string, optional): Session identifier
setUserTraits(params)
Set user properties.
Parameters:
params.userId(string): User identifierparams.traits(object): User properties
endUserSession(params)
End a user session.
Parameters:
params.userId(string): User identifierparams.sessionId(string): Session identifierparams.duration(number): Session duration in millisecondsparams.exitPage(string, optional): Last page visited
batchTrack(events)
Process multiple events in batch.
Parameters:
events(Array): Array of event objects
Configuration Options
const arise = new AriseServerAnalytics({
projectId: 'your-project-id', // Required
apiEndpoint: 'https://api.ariseapp.com', // Optional
timeout: 5000, // Request timeout in ms
retryAttempts: 3 // Number of retry attempts
});Error Handling
The SDK handles errors gracefully and won't crash your application:
try {
await arise.trackEvent({
userId: 'user123',
eventName: 'test_event'
});
} catch (error) {
console.error('Analytics tracking failed:', error);
// Your application continues normally
}TypeScript Support
Full TypeScript support with type definitions:
import { AriseServerAnalytics, AriseConfig } from '@toyef/arise-node';
const config: AriseConfig = {
projectId: 'your-project-id',
timeout: 5000
};
const arise = new AriseServerAnalytics(config);
// Type-safe event tracking
await arise.trackEvent({
userId: 'user123',
eventName: 'user_action',
properties: {
action_type: 'button_click',
element_id: 'submit_button'
}
});Performance Considerations
- Events are sent asynchronously and won't block your application
- Failed requests are automatically retried with exponential backoff
- Use batch tracking for high-volume scenarios
- Consider implementing a queue for critical applications
Security
- All data is transmitted over HTTPS
- API keys should be stored as environment variables
- User data is handled according to privacy regulations
License
MIT
Support
For issues and questions, please visit our documentation or create an issue on GitHub.
