
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@trackthatride/realtime
Advanced tools
Real-time tracking via Server-Sent Events for Track That Ride SDK
Real-time tracking session management for Track That Ride using Server-Sent Events (SSE). Provides automatic reconnection, state management, and event handling for live delivery tracking.
npm install @trackthatride/realtime
This package depends on @trackthatride/core, which will be installed automatically.
import { TrackingSession } from '@trackthatride/realtime';
// Create a tracking session
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app'
});
// Subscribe to updates
const unsubscribe = session.subscribe((state) => {
console.log('Ride status:', state.ride?.status);
console.log('Driver location:', state.currentLocation);
console.log('ETA:', state.estimatedArrival);
});
// Connect to a specific tracking code
await session.connect('TR123456789');
// Clean up when done
session.destroy();
unsubscribe();
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app', // Required: Your API base URL
apiKey?: string, // Optional: API key for authenticated endpoints
enableLogging?: boolean, // Optional: Enable debug logging (default: false)
autoConnect?: boolean, // Optional: Auto-connect on creation (default: false)
reconnectDelay?: number, // Optional: Delay between reconnect attempts in ms (default: 3000)
maxReconnectAttempts?: number // Optional: Max reconnection attempts (default: Infinity)
});
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app',
enableLogging: true, // See detailed logs
reconnectDelay: 5000, // Wait 5 seconds before reconnecting
maxReconnectAttempts: 10, // Give up after 10 attempts
autoConnect: false // Manual connection control
});
const session = new TrackingSession(config: TrackingSessionConfig);
Connect to a tracking code and start receiving real-time updates.
await session.connect('TR123456789');
Disconnect from the current tracking session and stop receiving updates.
session.disconnect();
Check if the session is currently connected.
if (session.isConnected()) {
console.log('Currently receiving live updates');
}
Get the current tracking state synchronously.
const state = session.getState();
if (state?.ride) {
console.log('Current status:', state.ride.status);
}
Subscribe to state changes. Returns an unsubscribe function.
const unsubscribe = session.subscribe((state) => {
console.log('State updated:', state);
});
// Later, when done
unsubscribe();
Listen to specific SSE events (status_update, location_update, error, etc.).
const unsubscribe = session.onSSEEvent('location_update', (data) => {
console.log('Driver moved to:', data.latitude, data.longitude);
});
Available events:
status_update: Ride status changedlocation_update: Driver location updatedeta_update: Estimated arrival time updateddriver_assigned: Driver assigned to rideerror: Error occurredconnected: Connection establisheddisconnected: Connection lostManually fetch the latest tracking data (useful for polling in background mode).
await session.refresh();
Clean up all resources, close connections, and remove all listeners.
session.destroy();
interface TrackingSessionState {
ride: Ride | null; // Current ride information
driver?: Driver | null; // Assigned driver information
currentLocation?: { // Real-time driver location
latitude: number;
longitude: number;
} | null;
estimatedArrival?: string | null; // ISO timestamp of estimated arrival
connectionStatus: ConnectionStatus; // Connection state
lastUpdate: string; // ISO timestamp of last update
}
type ConnectionStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
interface TrackingSessionConfig {
baseUrl: string; // Required: API base URL
apiKey?: string; // Optional: API key
enableLogging?: boolean; // Optional: Debug logging
autoConnect?: boolean; // Optional: Auto-connect on creation
reconnectDelay?: number; // Optional: Reconnection delay (ms)
maxReconnectAttempts?: number; // Optional: Max reconnection attempts
}
import { TrackingSession } from '@trackthatride/realtime';
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app'
});
// Subscribe to all state changes
const unsubscribe = session.subscribe((state) => {
console.log('Tracking Code:', state.ride?.tracking_code);
console.log('Status:', state.ride?.status);
console.log('Customer:', state.ride?.customer_name);
if (state.driver) {
console.log('Driver:', state.driver.firstName, state.driver.lastName);
}
if (state.currentLocation) {
console.log('Current Location:', state.currentLocation);
}
if (state.estimatedArrival) {
console.log('ETA:', new Date(state.estimatedArrival).toLocaleString());
}
});
// Connect to tracking code
await session.connect('TR123456789');
// Clean up
// unsubscribe();
// session.destroy();
Listen to specific events instead of subscribing to all state changes:
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app'
});
// Listen for status changes
session.onSSEEvent('status_update', (data) => {
console.log('Status changed to:', data.status);
if (data.status === 'delivered') {
console.log('Delivery completed!');
}
});
// Listen for driver location updates
session.onSSEEvent('location_update', (data) => {
console.log('Driver at:', data.latitude, data.longitude);
});
// Listen for ETA changes
session.onSSEEvent('eta_update', (data) => {
console.log('New ETA:', data.estimatedArrival);
});
// Listen for errors
session.onSSEEvent('error', (data) => {
console.error('Tracking error:', data.message);
});
await session.connect('TR123456789');
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app',
reconnectDelay: 3000,
maxReconnectAttempts: 5
});
const unsubscribe = session.subscribe((state) => {
switch (state.connectionStatus) {
case 'connecting':
console.log('Establishing connection...');
break;
case 'connected':
console.log('Connected! Receiving live updates');
break;
case 'reconnecting':
console.log('Connection lost, attempting to reconnect...');
break;
case 'disconnected':
console.log('Disconnected from tracking');
break;
}
});
await session.connect('TR123456789');
Useful for background updates or when SSE is not available:
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app',
autoConnect: false // Disable SSE
});
// Poll every 30 seconds
const interval = setInterval(async () => {
try {
await session.refresh();
const state = session.getState();
console.log('Status:', state?.ride?.status);
} catch (error) {
console.error('Failed to refresh:', error);
}
}, 30000);
// Initial fetch
await session.refresh();
// Clean up
// clearInterval(interval);
// session.destroy();
import { AppState } from 'react-native';
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app'
});
let backgroundTimer: NodeJS.Timeout | null = null;
// Handle app state changes
const handleAppStateChange = (nextAppState: string) => {
if (nextAppState === 'background') {
// App going to background - disconnect SSE
session.disconnect();
// Use polling instead to save battery
backgroundTimer = setInterval(async () => {
await session.refresh();
}, 30000); // 30 seconds
} else if (nextAppState === 'active') {
// App coming to foreground - resume SSE
if (backgroundTimer) {
clearInterval(backgroundTimer);
backgroundTimer = null;
}
await session.connect('TR123456789');
}
};
AppState.addEventListener('change', handleAppStateChange);
const sessions = new Map<string, TrackingSession>();
const createSession = (trackingCode: string) => {
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app'
});
session.subscribe((state) => {
console.log(`[${trackingCode}] Status:`, state.ride?.status);
});
session.connect(trackingCode);
sessions.set(trackingCode, session);
};
// Track multiple deliveries
createSession('TR123456789');
createSession('TR987654321');
createSession('TR555555555');
// Clean up all sessions
sessions.forEach(session => session.destroy());
sessions.clear();
import { TrackingSession } from '@trackthatride/realtime';
const session = new TrackingSession({
baseUrl: 'https://your-app.replit.app',
enableLogging: true
});
// Handle connection errors
try {
await session.connect('TR123456789');
} catch (error) {
console.error('Failed to connect:', error);
}
// Handle SSE errors
session.onSSEEvent('error', (errorData) => {
console.error('SSE Error:', errorData.message);
// Optionally disconnect on critical errors
if (errorData.critical) {
session.disconnect();
}
});
// Handle disconnections
session.subscribe((state) => {
if (state.connectionStatus === 'disconnected') {
console.log('Connection closed');
// Optionally attempt manual reconnection
}
});
Clean Up Resources: Always call destroy() when done to prevent memory leaks.
useEffect(() => {
const session = new TrackingSession({ baseUrl: '...' });
return () => session.destroy();
}, []);
Handle Connection States: Provide user feedback for different connection states.
Implement Error Handling: Always handle connection errors and SSE errors.
Use Reconnection Limits: Set reasonable maxReconnectAttempts to avoid infinite retries.
Enable Logging in Development: Use enableLogging: true during development.
Background Mode Strategy: For mobile apps, switch to polling mode when app goes to background.
Validate Tracking Codes: Verify tracking codes before connecting.
[disconnected] → connect() → [connecting] → [connected]
↓
reconnect() ← [reconnecting] ← connection lost
↓
[disconnected] (after max attempts)
The realtime package uses SSE for efficient, server-pushed updates. SSE provides:
The server sends these events through SSE:
status_update: Ride status changedlocation_update: Driver location updatedeta_update: ETA changeddriver_assigned: Driver assigned to ridedriver_unassigned: Driver removed from rideride_updated: General ride information updatedFull TypeScript support with exported types:
import {
TrackingSession,
TrackingSessionState,
TrackingSessionConfig,
ConnectionStatus,
StateCallback,
EventCallback,
UnsubscribeFunction
} from '@trackthatride/realtime';
Problem: Session won't connect
Solution:
baseUrl is correctProblem: Frequent reconnections
Solution:
reconnectDelayProblem: Connected but not receiving updates
Solution:
MIT
For support, please contact Track That Ride support or visit our documentation at /docs on your Track That Ride instance.
FAQs
Real-time tracking via Server-Sent Events for Track That Ride SDK
We found that @trackthatride/realtime demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.