diff --git a/loop/webui/src/timeline/data.ts b/loop/webui/src/timeline/data.ts
new file mode 100644
index 0000000..2130c21
--- /dev/null
+++ b/loop/webui/src/timeline/data.ts
@@ -0,0 +1,379 @@
+import { TimelineMessage } from "./types";
+import { formatNumber } from "./utils";
+
+/**
+ * Event types for data manager
+ */
+export type DataManagerEventType = 'dataChanged' | 'connectionStatusChanged';
+
+/**
+ * Connection status types
+ */
+export type ConnectionStatus = 'connected' | 'disconnected' | 'disabled';
+
+/**
+ * State interface
+ */
+export interface TimelineState {
+  hostname?: string;
+  working_dir?: string;
+  initial_commit?: string;
+  message_count?: number;
+  title?: string;
+  total_usage?: {
+    input_tokens: number;
+    output_tokens: number;
+    cache_read_input_tokens: number;
+    cache_creation_input_tokens: number;
+    total_cost_usd: number;
+  };
+}
+
+/**
+ * DataManager - Class to manage timeline data, fetching, and polling
+ */
+export class DataManager {
+  // State variables
+  private lastMessageCount: number = 0;
+  private nextFetchIndex: number = 0;
+  private currentFetchStartIndex: number = 0;
+  private currentPollController: AbortController | null = null;
+  private isFetchingMessages: boolean = false;
+  private isPollingEnabled: boolean = true;
+  private isFirstLoad: boolean = true;
+  private connectionStatus: ConnectionStatus = "disabled";
+  private messages: TimelineMessage[] = [];
+  private timelineState: TimelineState | null = null;
+  
+  // Event listeners
+  private eventListeners: Map<DataManagerEventType, Array<(...args: any[]) => void>> = new Map();
+
+  constructor() {
+    // Initialize empty arrays for each event type
+    this.eventListeners.set('dataChanged', []);
+    this.eventListeners.set('connectionStatusChanged', []);
+  }
+
+  /**
+   * Initialize the data manager and fetch initial data
+   */
+  public async initialize(): Promise<void> {
+    try {
+      // Initial data fetch
+      await this.fetchData();
+      // Start polling for updates only if initial fetch succeeds
+      this.startPolling();
+    } catch (error) {
+      console.error("Initial data fetch failed, will retry via polling", error);
+      // Still start polling to recover
+      this.startPolling();
+    }
+  }
+
+  /**
+   * Get all messages
+   */
+  public getMessages(): TimelineMessage[] {
+    return this.messages;
+  }
+
+  /**
+   * Get the current state
+   */
+  public getState(): TimelineState | null {
+    return this.timelineState;
+  }
+
+  /**
+   * Get the connection status
+   */
+  public getConnectionStatus(): ConnectionStatus {
+    return this.connectionStatus;
+  }
+
+  /**
+   * Get the isFirstLoad flag
+   */
+  public getIsFirstLoad(): boolean {
+    return this.isFirstLoad;
+  }
+
+  /**
+   * Get the currentFetchStartIndex
+   */
+  public getCurrentFetchStartIndex(): number {
+    return this.currentFetchStartIndex;
+  }
+
+  /**
+   * Add an event listener
+   */
+  public addEventListener(event: DataManagerEventType, callback: (...args: any[]) => void): void {
+    const listeners = this.eventListeners.get(event) || [];
+    listeners.push(callback);
+    this.eventListeners.set(event, listeners);
+  }
+
+  /**
+   * Remove an event listener
+   */
+  public removeEventListener(event: DataManagerEventType, callback: (...args: any[]) => void): void {
+    const listeners = this.eventListeners.get(event) || [];
+    const index = listeners.indexOf(callback);
+    if (index !== -1) {
+      listeners.splice(index, 1);
+      this.eventListeners.set(event, listeners);
+    }
+  }
+
+  /**
+   * Emit an event
+   */
+  private emitEvent(event: DataManagerEventType, ...args: any[]): void {
+    const listeners = this.eventListeners.get(event) || [];
+    listeners.forEach(callback => callback(...args));
+  }
+
+  /**
+   * Set polling enabled/disabled state
+   */
+  public setPollingEnabled(enabled: boolean): void {
+    this.isPollingEnabled = enabled;
+    
+    if (enabled) {
+      this.startPolling();
+    } else {
+      this.stopPolling();
+    }
+  }
+
+  /**
+   * Start polling for updates
+   */
+  public startPolling(): void {
+    this.stopPolling(); // Stop any existing polling
+    
+    // Start long polling
+    this.longPoll();
+  }
+
+  /**
+   * Stop polling for updates
+   */
+  public stopPolling(): void {
+    // Abort any ongoing long poll request
+    if (this.currentPollController) {
+      this.currentPollController.abort();
+      this.currentPollController = null;
+    }
+    
+    // If polling is disabled by user, set connection status to disabled
+    if (!this.isPollingEnabled) {
+      this.updateConnectionStatus("disabled");
+    }
+  }
+
+  /**
+   * Update the connection status
+   */
+  private updateConnectionStatus(status: ConnectionStatus): void {
+    if (this.connectionStatus !== status) {
+      this.connectionStatus = status;
+      this.emitEvent('connectionStatusChanged', status);
+    }
+  }
+
+  /**
+   * Long poll for updates
+   */
+  private async longPoll(): Promise<void> {
+    // Abort any existing poll request
+    if (this.currentPollController) {
+      this.currentPollController.abort();
+      this.currentPollController = null;
+    }
+
+    // If polling is disabled, don't start a new poll
+    if (!this.isPollingEnabled) {
+      return;
+    }
+
+    let timeoutId: number | undefined;
+
+    try {
+      // Create a new abort controller for this request
+      this.currentPollController = new AbortController();
+      const signal = this.currentPollController.signal;
+
+      // Get the URL with the current message count
+      const pollUrl = `state?poll=true&seen=${this.lastMessageCount}`;
+
+      // Make the long poll request
+      // Use explicit timeout to handle stalled connections (120s)
+      const controller = new AbortController();
+      timeoutId = window.setTimeout(() => controller.abort(), 120000);
+
+      interface CustomFetchOptions extends RequestInit {
+        [Symbol.toStringTag]?: unknown;
+      }
+
+      const fetchOptions: CustomFetchOptions = {
+        signal: controller.signal,
+        // Use the original signal to allow manual cancellation too
+        get [Symbol.toStringTag]() {
+          if (signal.aborted) controller.abort();
+          return "";
+        },
+      };
+
+      try {
+        const response = await fetch(pollUrl, fetchOptions);
+        // Clear the timeout since we got a response
+        clearTimeout(timeoutId);
+
+        // Parse the JSON response
+        const _data = await response.json();
+
+        // If we got here, data has changed, so fetch the latest data
+        await this.fetchData();
+
+        // Start a new long poll (if polling is still enabled)
+        if (this.isPollingEnabled) {
+          this.longPoll();
+        }
+      } catch (error) {
+        // Handle fetch errors inside the inner try block
+        clearTimeout(timeoutId);
+        throw error; // Re-throw to be caught by the outer catch block
+      }
+    } catch (error: unknown) {
+      // Clean up timeout if we're handling an error
+      if (timeoutId) clearTimeout(timeoutId);
+
+      // Don't log or treat manual cancellations as errors
+      const isErrorWithName = (
+        err: unknown,
+      ): err is { name: string; message?: string } =>
+        typeof err === "object" && err !== null && "name" in err;
+
+      if (
+        isErrorWithName(error) &&
+        error.name === "AbortError" &&
+        this.currentPollController?.signal.aborted
+      ) {
+        console.log("Polling cancelled by user");
+        return;
+      }
+
+      // Handle different types of errors with specific messages
+      let errorMessage = "Not connected";
+
+      if (isErrorWithName(error)) {
+        if (error.name === "AbortError") {
+          // This was our timeout abort
+          errorMessage = "Connection timeout - not connected";
+          console.error("Long polling timeout");
+        } else if (error.name === "SyntaxError") {
+          // JSON parsing error
+          errorMessage = "Invalid response from server - not connected";
+          console.error("JSON parsing error:", error);
+        } else if (
+          error.name === "TypeError" &&
+          error.message?.includes("NetworkError")
+        ) {
+          // Network connectivity issues
+          errorMessage = "Network connection lost - not connected";
+          console.error("Network error during polling:", error);
+        } else {
+          // Generic error
+          console.error("Long polling error:", error);
+        }
+      }
+
+      // Disable polling on error
+      this.isPollingEnabled = false;
+
+      // Update connection status to disconnected
+      this.updateConnectionStatus("disconnected");
+
+      // Emit an event that we're disconnected with the error message
+      this.emitEvent('connectionStatusChanged', this.connectionStatus, errorMessage);
+    }
+  }
+
+  /**
+   * Fetch timeline data
+   */
+  public async fetchData(): Promise<void> {    
+    // If we're already fetching messages, don't start another fetch
+    if (this.isFetchingMessages) {
+      console.log("Already fetching messages, skipping request");
+      return;
+    }
+
+    this.isFetchingMessages = true;
+
+    try {
+      // Fetch state first
+      const stateResponse = await fetch("state");
+      const state = await stateResponse.json();
+      this.timelineState = state;
+
+      // Check if new messages are available
+      if (
+        state.message_count === this.lastMessageCount &&
+        this.lastMessageCount > 0
+      ) {
+        // No new messages, early return
+        this.isFetchingMessages = false;
+        this.emitEvent('dataChanged', { state, newMessages: [] });
+        return;
+      }
+
+      // Fetch messages with a start parameter
+      this.currentFetchStartIndex = this.nextFetchIndex;
+      const messagesResponse = await fetch(
+        `messages?start=${this.nextFetchIndex}`,
+      );
+      const newMessages = await messagesResponse.json() || [];
+
+      // Store messages in our array
+      if (this.nextFetchIndex === 0) {
+        // If this is the first fetch, replace the entire array
+        this.messages = [...newMessages];
+      } else {
+        // Otherwise append the new messages
+        this.messages = [...this.messages, ...newMessages];
+      }
+
+      // Update connection status to connected
+      this.updateConnectionStatus("connected");
+
+      // Update the last message index for next fetch
+      if (newMessages && newMessages.length > 0) {
+        this.nextFetchIndex += newMessages.length;
+      }
+
+      // Update the message count
+      this.lastMessageCount = state?.message_count ?? 0;
+
+      // Mark that we've completed first load
+      if (this.isFirstLoad) {
+        this.isFirstLoad = false;
+      }
+
+      // Emit an event that data has changed
+      this.emitEvent('dataChanged', { state, newMessages, isFirstFetch: this.nextFetchIndex === newMessages.length });
+    } catch (error) {
+      console.error("Error fetching data:", error);
+
+      // Update connection status to disconnected
+      this.updateConnectionStatus("disconnected");
+
+      // Emit an event that we're disconnected
+      this.emitEvent('connectionStatusChanged', this.connectionStatus, "Not connected");
+    } finally {
+      this.isFetchingMessages = false;
+    }
+  }
+}
