const API_URL = 'https://alpenqueue.maxtheweb.com'; const SSE_URL = 'https://maxtheweb.com/events'; let eventSource = null; let currentJobId = null; let jobsQueued = 0; let resultsReceived = 0; // Initialize SSE connection function initSSE() { if (eventSource) { eventSource.close(); } eventSource = new EventSource(SSE_URL); eventSource.onopen = function() { console.log('SSE connection established'); updateConnectionStatus('connected'); }; eventSource.onmessage = function(event) { try { const data = JSON.parse(event.data); if (data.type === 'connected') { console.log('SSE handshake complete'); return; } if (data.type === 'result') { displayResult(data); } } catch (error) { console.error('Error parsing SSE message:', error); } }; eventSource.onerror = function(error) { console.error('SSE error:', error); updateConnectionStatus('disconnected'); // Reconnect after 5 seconds setTimeout(() => { if (eventSource.readyState === EventSource.CLOSED) { initSSE(); } }, 5000); }; } function updateConnectionStatus(status) { const indicator = document.getElementById('connection-status'); if (!indicator) return; indicator.className = 'connection-status ' + status; indicator.textContent = status === 'connected' ? '● Live' : '○ Reconnecting...'; } function displayResult(data) { const resultsContainer = document.getElementById('live-results'); if (!resultsContainer) return; // Remove the "no results" message if it exists const noResults = resultsContainer.querySelector('.no-results'); if (noResults) { noResults.remove(); } // Increment results received counter resultsReceived++; document.getElementById('results-received').textContent = resultsReceived; const resultDiv = document.createElement('div'); resultDiv.className = 'result-item ' + (data.status || 'ok'); const timestamp = new Date(data.timestamp).toLocaleTimeString(); resultDiv.innerHTML = `
${(data.status || 'OK').toUpperCase()} ${timestamp} · ${data.took || '0s'}
${data.url}
${data.content ? `
${escapeHtml(data.content.substring(0, 500))}${data.content.length > 500 ? '...' : ''}
` : 'No content extracted'}
`; // Add to top of results resultsContainer.insertBefore(resultDiv, resultsContainer.firstChild); // Limit to 10 results while (resultsContainer.children.length > 10) { resultsContainer.removeChild(resultsContainer.lastChild); } // Highlight animation resultDiv.style.animation = 'slideIn 0.3s ease-out'; } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Handle form submission document.getElementById('queue-form').addEventListener('submit', async (e) => { e.preventDefault(); const submitBtn = document.getElementById('submit-btn'); const responseDiv = document.getElementById('response'); // Get form values const url = document.getElementById('url').value; const selector = document.getElementById('selector').value; // Use our own webhook endpoint const webhook = 'https://maxtheweb.com/webhook'; // Update UI submitBtn.disabled = true; submitBtn.textContent = 'Queueing...'; responseDiv.className = 'response-box loading'; responseDiv.innerHTML = '
Sending to AlpenQueue...'; try { // Build the job payload const jobData = { url: url, selector: selector, // AlpenQueue expects a single string webhook_url: webhook // AlpenQueue expects webhook_url, not callback_url }; // Send to AlpenQueue API const response = await fetch(`${API_URL}/jobs`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(jobData) }); if (response.ok) { // AlpenQueue returns plain text like "Job 7 created" const resultText = await response.text(); const jobIdMatch = resultText.match(/Job (\d+) created/); const jobId = jobIdMatch ? jobIdMatch[1] : 'Processing'; currentJobId = jobId; // Increment jobs queued counter jobsQueued++; document.getElementById('jobs-queued').textContent = jobsQueued; responseDiv.className = 'response-box success'; responseDiv.innerHTML = `
Job Queued!
Job ID: ${jobId}
Results will appear below in real-time...
`; } else { throw new Error(`Server responded with ${response.status}`); } } catch (error) { responseDiv.className = 'response-box error'; responseDiv.innerHTML = `
Error:
${error.message}
Check the console for details
`; console.error('AlpenQueue Error:', error); } finally { submitBtn.disabled = false; submitBtn.textContent = 'Queue it →'; } }); // Initialize on load window.addEventListener('load', () => { // Pre-fill with a demo example document.getElementById('url').value = 'https://news.ycombinator.com'; document.getElementById('selector').value = '.athing .titleline'; // Start SSE connection initSSE(); }); // Cleanup on page unload window.addEventListener('beforeunload', () => { if (eventSource) { eventSource.close(); } });