The extension's messaging system has been unified and simplified using UnifiedMessaging.js with intelligent timeout management, replacing the complex Smart Messaging architecture. The system now provides direct runtime.sendMessage with action-specific timeouts for optimal performance while maintaining simplicity and reliability.
import { useMessaging } from '@/shared/messaging/composables/useMessaging.js'
import { MessageActions } from '@/shared/messaging/core/MessageActions.js'
export default {
setup() {
const { sendMessage, createMessage } = useMessaging('popup')
const translateText = async (text) => {
const message = createMessage(MessageActions.TRANSLATE, {
text,
targetLang: 'fa'
})
// UnifiedMessaging with streaming coordination for large translations
const response = await sendMessage(message)
return response.success ? response.data : null
}
const quickAction = async () => {
// Settings operations use fast 3-second timeout
const message = createMessage(MessageActions.GET_SETTINGS, {})
const response = await sendMessage(message)
return response
}
return { translateText, quickAction }
}
}import { sendMessage } from '@/shared/messaging/core/UnifiedMessaging.js'
import { MessageFormat, MessageActions } from '@/shared/messaging/core/MessagingCore.js'
// Send message with UnifiedMessaging
const message = MessageFormat.create(
MessageActions.TRANSLATE_SELECTION,
{ text: selectedText },
'content'
)
// UnifiedMessaging handles timeout and error management
const response = await sendMessage(message)
// Receive message with MessageHandler
import { createMessageHandler } from '@/shared/messaging/core/MessageHandler.js'
const messageHandler = createMessageHandler()
messageHandler.registerHandler(MessageActions.ACTIVATE_SELECT_ELEMENT_MODE, (message) => {
// Perform action
return { success: true, data: { status: 'done' } }
})
messageHandler.listen()import { MessageActions } from '@/shared/messaging/core/MessageActions.js'
import { createMessageHandler } from '@/shared/messaging/core/MessageHandler.js'
// Using centralized MessageHandler (recommended)
const messageHandler = createMessageHandler()
messageHandler.registerHandler(MessageActions.TRANSLATE, async (message) => {
const result = await handleTranslation(message.data)
return { success: true, data: result }
})
messageHandler.registerHandler(MessageActions.GET_PROVIDERS, async (message) => {
const providers = await getAvailableProviders()
return { success: true, data: providers }
})
messageHandler.listen()UnifiedMessaging automatically applies appropriate timeouts based on action complexity and provides streaming coordination for translation operations:
Fast Actions (3-second timeout):
GET_SETTINGS,SET_SETTINGS- 3000msGET_SELECT_ELEMENT_STATE- 2000msSHOW_NOTIFICATION- 2000msOPEN_SIDE_PANEL- 3000ms- UI and settings operations
Medium Actions (2-minute timeout):
TRANSLATE,TRANSLATE_SELECTION- 180000ms (to allow for AI model latency and background retries)TRANSLATE_TEXT- 180000msTEST_PROVIDER- 8000ms- Translation operations
Long Actions (20+ second timeout):
GOOGLE_TTS_SPEAK- 20000msSCREEN_CAPTURE- 25000msPROCESS_IMAGE_OCR- 30000ms- Media processing operations
Streaming Translation Support (Select Element Mode):
- Smart Timeout Management: Up to 300,000ms (5 minutes) for large content
- Progress Reporting: Real-time streaming updates with UnifiedTranslationCoordinator
- Fallback Handling: Graceful degradation from streaming to regular translation
- Context-Aware Routing: Automatic detection of streaming vs. regular translation needs
The messaging system is now fully integrated with the Unified Translation Service for centralized coordination of all translation operations:
Field Mode Translation (Direct Response):
- Request-Response Pattern: Field mode uses direct response pattern with intelligent timeout management
- No Broadcast Needed: Results are returned directly to the requesting content script
- Duplicate Prevention: UnifiedTranslationService prevents duplicate processing via request tracking
- Element Recovery: Smart element data recovery with TranslationRequestTracker
Select Element Mode (Streaming):
- Streaming Coordination: Large translations automatically use streaming via UnifiedTranslationCoordinator
- Frame-targeted Results: Results route to the originating tab/frame for streaming updates
- Progress Tracking: Real-time progress updates with proper request lifecycle management
Architecture Benefits:
- Centralized Coordination: All translation requests flow through UnifiedTranslationService
- Request Tracking: Comprehensive tracking prevents duplicate processing
- Intelligent Dispatch: Results are routed appropriately based on translation mode
- Error Handling: Centralized error management with proper cleanup
- Eliminated race conditions between competing listeners
- Action-specific timeouts prevent unnecessary delays
- Streaming coordination for large translation operations
- Centralized error handling with ExtensionContextManager
- Simplified architecture - no complex port fallbacks
- Smart timeout calculation based on content complexity
import { sendMessage } from '@/shared/messaging/core/UnifiedMessaging.js'
// Default timeout based on action (recommended)
const response = await sendMessage(message)
// Custom timeout override
const response = await sendMessage(message, { timeout: 10000 })All available actions in MessageActions.js:
// Translation
MessageActions.TRANSLATE
MessageActions.TRANSLATE_SELECTION
MessageActions.TRANSLATE_PAGE
MessageActions.GET_PROVIDERS
// Select Element
MessageActions.ACTIVATE_SELECT_ELEMENT_MODE
MessageActions.PROCESS_SELECTED_ELEMENT
// Streaming Translation (New)
MessageActions.TRANSLATION_STREAM_UPDATE // Real-time translation progress
MessageActions.TRANSLATION_STREAM_END // Translation completion
MessageActions.TRANSLATION_RESULT_UPDATE // Final result delivery
// TTS
MessageActions.GOOGLE_TTS_SPEAK
MessageActions.TTS_STOP
// Sidepanel
MessageActions.OPEN_SIDE_PANEL
MessageActions.SELECTED_TEXT_FOR_SIDEPANEL
// Coordination
MessageActions.CANCEL_TRANSLATION // Cancel ongoing translations{
action: 'TRANSLATE', // Operation type
data: { text: 'Hello' }, // Required data
context: 'popup', // Message source
messageId: 'unique-id', // Unique identifier
timestamp: 1672531200000 // Creation time
}{
success: true,
data: { translatedText: 'Hello' },
messageId: 'original-id',
timestamp: 1672531200000
}{
success: false,
error: {
message: 'Translation failed',
type: 'PROVIDER_ERROR'
},
messageId: 'original-id',
timestamp: 1672531200000
}MessagingContexts.POPUP // popup.html
MessagingContexts.SIDEPANEL // sidepanel.html
MessagingContexts.OPTIONS // options.html
MessagingContexts.BACKGROUND // background script
MessagingContexts.CONTENT // content script
MessagingContexts.OFFSCREEN // offscreen document// Use MessageFormat
const message = MessageFormat.create(action, data, context)
// Validate messages
if (!MessageFormat.validate(message)) {
console.warn('Invalid message format')
return
}
// Filter by context
if (message.context !== 'sidepanel') {
return false // Not for us
}// ❌ Manual message without MessageFormat
const badMessage = { action: 'TRANSLATE', text: 'hello' }
// ❌ Catch all messages without filtering
browser.runtime.onMessage.addListener((message) => {
// All messages are processed!
})
// ❌ Forgetting sendResponse
browser.runtime.onMessage.addListener((message) => {
doSomething()
// Forgot sendResponse or return true
})import { createLogger } from '@/shared/logging/logger.js'
const logger = createLogger('Messaging', 'debug')
// Log messages
logger.debug('Sending message:', message.action)
logger.error('Message failed:', error)- Open Extension DevTools
- Go to Console
- Filter with
[Messaging]
src/shared/messaging/
├── core/
│ ├── MessagingCore.js # MessageFormat, Contexts, utilities
│ ├── MessageActions.js # All available actions
│ ├── UnifiedMessaging.js # Unified messaging system
│ ├── UnifiedTranslationCoordinator.js # Translation streaming coordination
│ ├── StreamingTimeoutManager.js # Smart timeout management for streaming
│ ├── StreamingResponseHandler.js # Streaming response coordination
│ ├── ContentScriptIntegration.js # Content script integration layer
│ └── MessageHandler.js # Centralized message handling
├── composables/
│ └── useMessaging.js # Vue composable (uses UnifiedMessaging)
└── __tests__/
└── MessagingCore.test.js
src/core/services/translation/
├── UnifiedTranslationService.js # Centralized translation coordination
├── TranslationRequestTracker.js # Request lifecycle management
├── UnifiedResultDispatcher.js # Intelligent result routing
└── UnifiedModeCoordinator.js # Mode-specific logic coordination
Message not received?
- Check if message listener is properly registered
- Use correct context
- Verify with
MessageFormat.validate()
Cross-component interference?
- Use context filtering
- Generate unique messageIds
Performance issues?
- Don't send large data
- Check for message loops
Summary: UnifiedMessaging provides race-condition-free messaging with intelligent timeout management and streaming coordination. The new UnifiedTranslationCoordinator ensures efficient handling of large translation operations while maintaining context isolation and automatic fallback capabilities.