Events & Callbacks
The widget communicates with your application through standard DOM Custom Events. All events bubble and are composed (they cross the Shadow DOM boundary), so you can listen on the widget element or any ancestor.
Listening to Events
Section titled “Listening to Events”const widget = document.querySelector('ats-widget');
widget.addEventListener('allfeat:complete', (e) => { console.log(e.detail); // Event payload});Lifecycle
Section titled “Lifecycle”Events follow the registration flow:
ready → upload-start → upload-progress (×N) → upload-complete → confirmed → step (×N) → completeOn error at any stage:
... → failedToken expiry can occur at any point:
... → token-expired → (setToken) → retryAvailable Events
Section titled “Available Events”allfeat:ready
Section titled “allfeat:ready”Emitted when the widget is initialized and ready.
{ mode: 'register' | 'update' | 'access' }allfeat:upload-start
Section titled “allfeat:upload-start”Emitted when the audio file upload begins.
{ filename: string; size: number }allfeat:upload-progress
Section titled “allfeat:upload-progress”Emitted repeatedly during upload. Useful for displaying an external progress bar.
{ progress: number; loaded: number; total: number }// progress: 0–100 (percentage)allfeat:upload-complete
Section titled “allfeat:upload-complete”Emitted when the upload finishes successfully.
{ filename: string }allfeat:confirmed
Section titled “allfeat:confirmed”Emitted when the blockchain transaction has been submitted.
{ transactionId: string }allfeat:step
Section titled “allfeat:step”Emitted on each blockchain tracking step change.
{ step: 'validating' | 'transferring_tokens' | 'preparing_transaction' | 'signing' | 'submitting' | 'confirming'; progress: number; // 0–100 description?: string;}allfeat:complete
Section titled “allfeat:complete”Emitted when the work is successfully registered on the blockchain.
{ atsId: number | null; // Unique work identifier txHash: string; // Blockchain transaction hash blockNumber: number; // Block number explorerUrl: string; // Blockchain explorer URL accessCode?: string; // Access code (register mode only)}allfeat:failed
Section titled “allfeat:failed”Emitted when a critical error occurs.
{ error: string; // Error message stage?: string; // Stage where the error occurred code?: string; // Error code (see Reference > Error Codes)}allfeat:token-expired
Section titled “allfeat:token-expired”Emitted when the JWT token has expired (401 response).
{ pendingAction: string }After receiving this event, call widget.setToken(newToken) so the widget automatically retries the pending action. You have 60 seconds before the widget transitions to a failed state.
allfeat:error
Section titled “allfeat:error”Emitted for non-fatal errors (the widget can continue operating).
{ stage: string; error: string; code?: string; details?: unknown;}Example: Full Tracking
Section titled “Example: Full Tracking”const widget = document.querySelector('ats-widget');
widget.addEventListener('allfeat:ready', (e) => { console.log(`Widget ready in ${e.detail.mode} mode`);});
widget.addEventListener('allfeat:upload-progress', (e) => { updateProgressBar(e.detail.progress);});
widget.addEventListener('allfeat:step', (e) => { updateStatusMessage(e.detail.description);});
widget.addEventListener('allfeat:complete', (e) => { const { atsId, txHash, accessCode } = e.detail; showSuccess(`ATS #${atsId} — TX: ${txHash}`);
if (accessCode) { // Save access code for future operations saveToDatabase({ atsId, accessCode }); }});
widget.addEventListener('allfeat:failed', (e) => { showError(e.detail.error); reportToSentry(e.detail);});
widget.addEventListener('allfeat:token-expired', async () => { const { token } = await refreshToken(); widget.setToken(token);});