Events API
⚡ 10 min readThe Transcodes SDK provides an event system to subscribe to authentication state changes, token updates, errors, and admin-side member revocations
Event Methods
on()
Subscribes to an event. Returns an unsubscribe function.
transcodes.on<T extends TranscodesEventName>(
event: T,
callback: (payload: EventPayload<T>) => void
): () => voidThe on() method returns a function that unsubscribes the listener when
called. This is the recommended way to manage subscriptions
Example:
// Subscribe and get unsubscribe function
const unsubscribe = transcodes.on('AUTH_STATE_CHANGED', (payload) => {
console.log('Auth state:', payload.isAuthenticated);
});
// Later: unsubscribe
unsubscribe();off()
Removes an event listener. Requires the same function reference that was passed to on()
transcodes.off<T extends TranscodesEventName>(
event: T,
callback: (payload: EventPayload<T>) => void
): voidExample:
// Store the handler reference
const handleAuthChange = (payload) => {
console.log('Auth changed:', payload.isAuthenticated);
};
// Subscribe
transcodes.on('AUTH_STATE_CHANGED', handleAuthChange);
// Unsubscribe (same function reference required)
transcodes.off('AUTH_STATE_CHANGED', handleAuthChange);Available Events
The SDK provides five events:
| Event Name | Description |
|---|---|
AUTH_STATE_CHANGED | Authentication state changed (login/logout) |
TOKEN_REFRESHED | Access token was refreshed |
TOKEN_EXPIRED | Token expired |
ERROR | SDK error occurred |
MEMBER_REVOKED | Current member was suspended/revoked by an admin (session already wiped) |
AUTH_STATE_CHANGED
Emitted when the authentication state changes (login, logout)
interface AuthStateChangedPayload {
isAuthenticated: boolean;
accessToken: string | null;
expiresAt: number | null;
member: Member | null;
}Example:
transcodes.on('AUTH_STATE_CHANGED', (payload) => {
if (payload.isAuthenticated) {
console.log('Member signed in');
console.log('Token expires at:', new Date(payload.expiresAt));
} else {
console.log('Member signed out');
}
});TOKEN_REFRESHED
Emitted when the access token is automatically refreshed
interface TokenRefreshedPayload {
accessToken: string;
expiresAt: number;
}Example:
transcodes.on('TOKEN_REFRESHED', (payload) => {
console.log('Token refreshed');
console.log('New expiry:', new Date(payload.expiresAt));
// Update your API client if needed
apiClient.setToken(payload.accessToken);
});TOKEN_EXPIRED
Emitted when the token expires and cannot be refreshed
interface TokenExpiredPayload {
expiredAt: number;
}Example:
transcodes.on('TOKEN_EXPIRED', (payload) => {
console.log('Token expired at:', new Date(payload.expiredAt));
// Prompt user to log in again
showNotification('Session expired. Please log in again.');
window.location.href = '/login';
});ERROR
Emitted when the SDK encounters an error
interface ErrorPayload {
code: string;
message: string;
context?: string;
}Example:
transcodes.on('ERROR', (payload) => {
console.error(`[${payload.context}] ${payload.code}: ${payload.message}`);
// Send to error tracking service
errorTracker.captureError({
name: 'TranscodesError',
code: payload.code,
message: payload.message,
context: payload.context,
});
});MEMBER_REVOKED
Emitted when the server reports that the current member has been suspended or revoked by an admin. By the time this event fires, the SDK has already cleared the local session — your handler does not need to call signOut() or clear tokens manually. It only needs to surface a notice and route the user out.
interface MemberRevokedPayload {
/** User-facing message to display */
message: string;
/** Machine-readable reason for programmatic handling */
reason: 'member_revoked';
}This event fires asynchronously when the server detects the revocation (typically on the next API call or token refresh). Subscribe at app startup so the redirect happens regardless of which screen the user is currently on.
Example:
transcodes.on('MEMBER_REVOKED', ({ message, reason }) => {
// reason === 'member_revoked'
// 1. Show the user-facing message (toast / banner / alert)
showNotification(message);
// 2. Send the user back to the sign-in screen
window.location.href = '/login?reason=member_revoked';
});React example with cleanup:
useEffect(() => {
const unsubscribe = transcodes.on('MEMBER_REVOKED', ({ message }) => {
toast.error(message);
router.push('/login?reason=member_revoked');
});
return () => unsubscribe();
}, []);Usage Patterns
Subscribe to Multiple Events
// Store unsubscribe functions
const subscriptions = [];
// Subscribe to events
subscriptions.push(
transcodes.on('AUTH_STATE_CHANGED', (payload) => {
console.log('Auth state:', payload.isAuthenticated);
if (payload.member) {
console.log('Member:', payload.member.email);
}
})
);
subscriptions.push(
transcodes.on('TOKEN_EXPIRED', (payload) => {
console.log('Token expired');
window.location.href = '/login';
})
);
subscriptions.push(
transcodes.on('ERROR', (payload) => {
console.error('Error:', payload.code, payload.message);
})
);
// Later: cleanup all subscriptions
subscriptions.forEach((unsubscribe) => unsubscribe());Best Practices
1. Always Cleanup Subscriptions
// Subscribe
const unsubscribe = transcodes.on('AUTH_STATE_CHANGED', handler);
// Later: cleanup when no longer needed
unsubscribe();Failing to unsubscribe can cause memory leaks, especially in Single Page Applications
2. Use the Returned Unsubscribe Function
// Recommended: use returned function
const unsubscribe = transcodes.on('AUTH_STATE_CHANGED', handler);
unsubscribe();
// Alternative: use off() with same reference
const handler = (payload) => {
/* ... */
};
transcodes.on('AUTH_STATE_CHANGED', handler);
transcodes.off('AUTH_STATE_CHANGED', handler);3. Subscribe to ERROR Events
// Always handle errors
transcodes.on('ERROR', (payload) => {
console.error('Transcodes error:', payload);
// Send to monitoring service
});4. Avoid Heavy Operations in Handlers
// Bad: heavy operation in handler
transcodes.on('AUTH_STATE_CHANGED', async (payload) => {
await heavyDatabaseOperation(); // Blocks other handlers
});
// Good: defer heavy operations
transcodes.on('AUTH_STATE_CHANGED', (payload) => {
setTimeout(() => heavyDatabaseOperation(), 0);
});Type Definitions
Event Names
type TranscodesEventName =
| 'AUTH_STATE_CHANGED'
| 'TOKEN_REFRESHED'
| 'TOKEN_EXPIRED'
| 'ERROR'
| 'MEMBER_REVOKED';Event Payloads
interface TranscodesEventMap {
AUTH_STATE_CHANGED: AuthStateChangedPayload;
TOKEN_REFRESHED: TokenRefreshedPayload;
TOKEN_EXPIRED: TokenExpiredPayload;
ERROR: ErrorPayload;
MEMBER_REVOKED: MemberRevokedPayload;
}
interface AuthStateChangedPayload {
isAuthenticated: boolean;
accessToken: string | null;
expiresAt: number | null;
member: Member | null;
}
interface TokenRefreshedPayload {
accessToken: string;
expiresAt: number;
}
interface TokenExpiredPayload {
expiredAt: number;
}
interface ErrorPayload {
code: string;
message: string;
context?: string;
}
interface MemberRevokedPayload {
message: string;
reason: 'member_revoked';
}Related
- Token API - Token management
- Member API - Member profile
- Modal API - Authentication modals
- Types - Event payload types