Networking
Enhanced Fetch, WebSocket, SSE, and WebTransport.
Enhanced Fetch
fetchJSON with retry, dedup, timeout. fetchOffline queues when offline.
Ready...
import { enhance } from 'weblisk'; import { fetchJSON, fetchOffline } from 'weblisk/net/fetch.js'; enhance('#demo-fetch', (el, { $ }) => { $('#btn-fetch').addEventListener('click', async () => { $('#output-fetch').textContent = 'Fetching...'; try { const data = await fetchJSON( 'https://jsonplaceholder.typicode.com/posts?_limit=5', { timeout: 5000 } ); $('#output-fetch').textContent = `Loaded ${data.length} posts:\n` + data.map(p => p.title).join('\n'); } catch (err) { $('#output-fetch').textContent = `Error: ${err.message}`; } }); $('#btn-fetch-offline').addEventListener('click', async () => { try { const result = await fetchOffline('/api/analytics', { method: 'POST', body: JSON.stringify({ event: 'demo', timestamp: Date.now() }) }); $('#output-fetch').textContent = result.queued ? 'Request queued for when back online' : `Sent (status ${result.status})`; } catch (err) { $('#output-fetch').textContent = `Queued: ${err.message}`; } }); });
WebSocket
Reactive WebSocket with auto-reconnect, heartbeat, and message buffering.
Disconnected
import { effect, enhance } from 'weblisk'; import { socket } from 'weblisk/net/ws.js'; enhance('#demo-ws', (el, { $ }) => { let conn = null; $('#btn-ws').addEventListener('click', () => { if (conn) { conn.close(); conn = null; } conn = socket('wss://echo.websocket.org', { reconnect: false, heartbeat: 0 }); effect(() => { const s = conn.state(); let text = `State: ${s}\n`; const msgs = conn.messages(); if (msgs.length) { text += `Messages: ${msgs.length}\n`; text += msgs.slice(-3) .map(m => ` → ${JSON.stringify(m)}`) .join('\n'); } $('#output-ws').textContent = text; }); }); });
Server-Sent Events
Reactive SSE with named event channels and auto-reconnect.
No events
import { effect, enhance } from 'weblisk'; import { stream, latest } from 'weblisk/net/sse.js'; enhance('#demo-sse', (el, { $ }) => { let conn = null; $('#btn-sse').addEventListener('click', () => { if (conn) { conn.close(); conn = null; } conn = stream('/api/events'); const last = latest(conn.events); effect(() => { const s = conn.status(); let text = `Status: ${s}\n`; const evts = conn.events(); if (evts.length) { text += `Events: ${evts.length}\n`; const recent = last(); if (recent) text += `Latest: ${JSON.stringify(recent.data)}`; } $('#output-sse').textContent = text; }); }); });
Real-Time Transport
Unified WebTransport (HTTP/3) → WebSocket fallback. Multiplexed channels, auto-reconnect.
Ready...
import { effect, enhance } from 'weblisk'; import { transport } from 'weblisk/net/transport.js'; enhance('#demo-transport', (el, { $ }) => { $('#btn-transport').addEventListener('click', () => { const hasWT = typeof WebTransport !== 'undefined'; const hasWS = typeof WebSocket !== 'undefined'; const conn = transport('wss://echo.websocket.org', { reconnect: false, heartbeat: 0 }); effect(() => { const s = conn.state(); let text = `WebTransport: ${hasWT ? 'Yes' : 'No'}\n`; text += `WebSocket: ${hasWS ? 'Yes' : 'No'}\n`; text += `State: ${s}\n`; text += `Using: ${hasWT ? 'WebTransport' : 'WebSocket'}`; $('#output-transport').textContent = text; }); }); });