rapid interations of server side app and firefox extension

This commit is contained in:
Bryan Van Deusen
2026-01-24 22:52:51 -05:00
commit b9b8048a2d
81 changed files with 9675 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
import { ref, onMounted, onUnmounted } from 'vue'
const WS_URL = `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}/ws/events`
// Singleton WebSocket connection
let ws = null
let reconnectTimeout = null
const listeners = new Map()
const isConnected = ref(false)
const lastEvent = ref(null)
function connect() {
if (ws && ws.readyState === WebSocket.OPEN) {
return
}
try {
ws = new WebSocket(WS_URL)
ws.onopen = () => {
console.log('WebSocket connected')
isConnected.value = true
}
ws.onclose = () => {
console.log('WebSocket disconnected')
isConnected.value = false
ws = null
// Reconnect after 5 seconds
if (!reconnectTimeout) {
reconnectTimeout = setTimeout(() => {
reconnectTimeout = null
connect()
}, 5000)
}
}
ws.onerror = (error) => {
console.error('WebSocket error:', error)
}
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
lastEvent.value = data
// Handle ping
if (data.type === 'ping') {
ws.send(JSON.stringify({ type: 'pong' }))
return
}
// Notify all listeners for this event type
const typeListeners = listeners.get(data.type) || []
typeListeners.forEach(callback => {
try {
callback(data.data)
} catch (e) {
console.error('Error in WebSocket listener:', e)
}
})
// Also notify wildcard listeners
const wildcardListeners = listeners.get('*') || []
wildcardListeners.forEach(callback => {
try {
callback(data.type, data.data)
} catch (e) {
console.error('Error in WebSocket listener:', e)
}
})
} catch (e) {
console.error('Failed to parse WebSocket message:', e)
}
}
} catch (e) {
console.error('Failed to create WebSocket:', e)
}
}
function disconnect() {
if (reconnectTimeout) {
clearTimeout(reconnectTimeout)
reconnectTimeout = null
}
if (ws) {
ws.close()
ws = null
}
isConnected.value = false
}
function subscribe(eventType, callback) {
if (!listeners.has(eventType)) {
listeners.set(eventType, [])
}
listeners.get(eventType).push(callback)
// Return unsubscribe function
return () => {
const typeListeners = listeners.get(eventType)
if (typeListeners) {
const index = typeListeners.indexOf(callback)
if (index > -1) {
typeListeners.splice(index, 1)
}
}
}
}
function send(type, data = {}) {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type, data }))
}
}
export function useWebSocket() {
onMounted(() => {
connect()
})
return {
isConnected,
lastEvent,
subscribe,
send,
connect,
disconnect,
}
}
// Auto-connect on import
if (typeof window !== 'undefined') {
connect()
}