Research Objective
Investigate WebSocket management and SSE streaming patterns for Chat and Search Web Components.
Current State
- Chat uses WebSocket for real-time messaging (Chat.svelte)
- Search uses EventSource (SSE) for summarization updates (Search.svelte)
- Connection state management in Svelte lifecycle
- Tauri uses polling fallback (no EventSource support)
- Automatic reconnection on error
References:
- Chat WebSocket:
desktop/src/lib/Chat/Chat.svelte
- Search SSE:
desktop/src/lib/Search/Search.svelte:102-224
Research Questions
- How to manage WebSocket/SSE lifecycle in Web Components?
- Connection state management patterns?
- Automatic reconnection strategies?
- Memory leak prevention?
- Multiple component instances sharing connections?
- Fallback strategies (polling for Tauri)?
Streaming Patterns to Evaluate
Pattern 1: Component-Owned Connection
Each component manages its own connection.
Pros:
- Simple, self-contained
- Component controls lifecycle
- Easy to reason about
Cons:
- Multiple connections for same data
- Resource waste
- Reconnection complexity
Implementation:
class TerraphimChat extends HTMLElement {
connectedCallback() {
this.ws = new WebSocket(this.wsUrl);
this.ws.onmessage = (e) => this.handleMessage(e);
this.ws.onerror = () => this.reconnect();
}
disconnectedCallback() {
this.ws?.close();
}
}
Pattern 2: Shared Connection Service
Singleton service manages connections, components subscribe.
Pros:
- Single connection shared
- Centralized error handling
- Efficient resource use
Cons:
- Need pub/sub system
- State management complexity
- Service lifecycle management
Implementation:
// Singleton service
class WebSocketService {
subscribe(channel, handler) { ... }
unsubscribe(channel, handler) { ... }
}
// Component uses service
class TerraphimChat extends HTMLElement {
connectedCallback() {
this.handler = (msg) => this.handleMessage(msg);
wsService.subscribe('chat', this.handler);
}
disconnectedCallback() {
wsService.unsubscribe('chat', this.handler);
}
}
Pattern 3: Custom Element with Connection Attribute
Parent manages connection, children receive via attribute/property.
Pros:
- Flexible composition
- Parent controls connection
- Children remain simple
Cons:
- Tight coupling
- Complex prop passing
Implementation:
<terraphim-connection url="ws://...">
<terraphim-chat></terraphim-chat>
<terraphim-notifications></terraphim-notifications>
</terraphim-connection>
Lifecycle Management
Connection States
- Disconnected - Initial state
- Connecting - Establishing connection
- Connected - Active connection
- Reconnecting - Attempting to reconnect
- Failed - Permanent failure
State Machine
Disconnected -> Connecting -> Connected
↓ ↓
Failed Reconnecting
↓
Connected
Reconnection Strategy
- Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s
- Max retries: Configurable (default: infinite)
- Jitter: Random delay to prevent thundering herd
- Health check: Ping/pong to detect stale connections
Memory Leak Prevention
Common Pitfalls:
- Not closing connections on component removal
- Event listener leaks - not removing listeners
- Circular references - component refs in closures
- Pending reconnect timers - not clearing timeouts
Solutions:
class TerraphimChat extends HTMLElement {
disconnectedCallback() {
// Close connection
this.ws?.close();
// Clear timers
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
}
// Remove listeners
this.ws = null;
}
}
Tauri Fallback Strategy
Problem:
Tauri doesn't support EventSource (SSE), needs polling fallback.
Solution:
Detect environment and use appropriate strategy.
class TerraphimSearch extends HTMLElement {
startStreaming() {
if (this.isTauri) {
this.startPolling();
} else {
this.startSSE();
}
}
startPolling() {
this.pollInterval = setInterval(
() => this.fetchUpdate(),
2000
);
}
startSSE() {
this.eventSource = new EventSource(this.url);
this.eventSource.onmessage = (e) => this.handleUpdate(e);
}
}
Features to Maintain
Chat WebSocket:
Search SSE:
New Requirements:
Technical Challenges
Challenge 1: Reconnection UX
Problem: How to indicate reconnecting state to user?
Solution:
- Emit custom events for state changes
- Parent can show notification/banner
- Component-level indicators
Challenge 2: Message Ordering
Problem: Messages may arrive out of order during reconnect
Solution:
- Sequence numbers
- Message buffering
- Conflict resolution
Challenge 3: Shared State
Problem: Multiple components need same stream data
Solution:
- Pub/sub pattern
- State management integration
- Observable streams
Challenge 4: Testing
Problem: Hard to test WebSocket/SSE behavior
Solution:
- Mock WebSocket/EventSource
- Dependency injection
- Simulate network conditions
Acceptance Criteria
References
Documentation
Findings will be documented in: .docs/research-websocket-patterns.md
Research Objective
Investigate WebSocket management and SSE streaming patterns for Chat and Search Web Components.
Current State
References:
desktop/src/lib/Chat/Chat.sveltedesktop/src/lib/Search/Search.svelte:102-224Research Questions
Streaming Patterns to Evaluate
Pattern 1: Component-Owned Connection
Each component manages its own connection.
Pros:
Cons:
Implementation:
Pattern 2: Shared Connection Service
Singleton service manages connections, components subscribe.
Pros:
Cons:
Implementation:
Pattern 3: Custom Element with Connection Attribute
Parent manages connection, children receive via attribute/property.
Pros:
Cons:
Implementation:
Lifecycle Management
Connection States
State Machine
Reconnection Strategy
Memory Leak Prevention
Common Pitfalls:
Solutions:
Tauri Fallback Strategy
Problem:
Tauri doesn't support
EventSource(SSE), needs polling fallback.Solution:
Detect environment and use appropriate strategy.
Features to Maintain
Chat WebSocket:
Search SSE:
New Requirements:
Technical Challenges
Challenge 1: Reconnection UX
Problem: How to indicate reconnecting state to user?
Solution:
Challenge 2: Message Ordering
Problem: Messages may arrive out of order during reconnect
Solution:
Challenge 3: Shared State
Problem: Multiple components need same stream data
Solution:
Challenge 4: Testing
Problem: Hard to test WebSocket/SSE behavior
Solution:
Acceptance Criteria
References
desktop/src/lib/Chat/Chat.sveltedesktop/src/lib/Search/Search.svelteDocumentation
Findings will be documented in:
.docs/research-websocket-patterns.md