Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • migrate from zustand for console terminal logs to indexedDb, incr limit from 5mb to ~GBs (80% of free space on chrome)

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
docs Skipped Skipped Jan 14, 2026 6:30am

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 14, 2026

Greptile Summary

This PR migrates console terminal logs from Zustand's default localStorage storage to IndexedDB using idb-keyval, increasing storage capacity from ~5MB to tens of GBs (80% of available browser storage on Chrome).

Key Changes:

  • Created new storage.ts implementing Zustand's StateStorage interface with IndexedDB operations
  • Added one-time migration from localStorage to IndexedDB with proper promise handling
  • Integrated _hasHydrated flag to prevent rendering stale data during async hydration
  • Components now wait for hydration before displaying entries, preventing flash of empty state
  • Fixed hydration setup order to handle both callback registration and already-hydrated scenarios

Implementation Quality:

  • Migration promise properly cleared after completion (addressed in follow-up commit)
  • Hydration pattern follows existing store conventions (useTerminalStore, usePanelStore)
  • Error handling in place for all IndexedDB operations
  • SSR-safe with typeof window checks throughout

Confidence Score: 4/5

  • This PR is safe to merge with low risk; the implementation follows established patterns and handles edge cases well
  • The migration is well-implemented with proper error handling, SSR safety, and follows the codebase's Zustand patterns. The author addressed previous review feedback by fixing the hydration setup order and clearing the migration promise. Only minor concerns exist around the unconventional use of onFinishHydration outside the persist config, but the implementation correctly handles both callback and already-hydrated states.
  • No files require special attention

Important Files Changed

Filename Overview
apps/sim/stores/terminal/console/storage.ts introduced IndexedDB storage adapter with localStorage migration; migration promise properly cleared after completion
apps/sim/stores/terminal/console/store.ts integrated IndexedDB storage with hydration tracking; fixed hydration setup order to handle both callback and already-hydrated states
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/chat.tsx added hydration check to prevent rendering stale entries during async storage load
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx added hydration check to prevent rendering stale entries during async storage load

Sequence Diagram

sequenceDiagram
    participant App as Application Load
    participant Storage as storage.ts
    participant IDB as IndexedDB
    participant LS as localStorage
    participant Store as Zustand Store
    participant Component as Terminal/Chat Component

    Note over App,Component: Initial Load & Migration
    App->>Storage: Module loads
    Storage->>Storage: Start migrateFromLocalStorage()
    Storage->>IDB: Check MIGRATION_KEY
    alt Not migrated yet
        Storage->>LS: Get terminal-console-store
        LS-->>Storage: Return old data
        Storage->>IDB: Write terminal-console-store
        Storage->>LS: Remove terminal-console-store
        Storage->>IDB: Write MIGRATION_KEY flag
    end
    Storage->>Storage: Clear migrationPromise

    Note over Store,Component: Store Hydration
    App->>Store: Initialize useTerminalConsoleStore
    Store->>Storage: getItem from storage
    Storage->>Storage: Wait for migrationPromise
    Storage->>IDB: Read persisted data
    IDB-->>Storage: Return data
    Storage-->>Store: Return persisted state
    Store->>Store: Rehydrate entries and isOpen
    Store->>Store: Trigger onFinishHydration callback
    Store->>Store: Update hasHydrated flag

    Note over Component: Component Render
    Component->>Store: Subscribe to hasHydrated flag
    Component->>Store: Subscribe to entries
    alt Not hydrated
        Component->>Component: Render with empty entries
    else Hydrated
        Component->>Component: Render with entriesFromStore
    end

    Note over Store,IDB: Adding New Console Entry
    App->>Store: addConsole new entry
    Store->>Store: Process and trim entries
    Store->>Storage: setItem auto-persist
    Storage->>IDB: Write updated data
    IDB-->>Storage: Success
    Component->>Component: Re-render with new entry
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@waleedlatif1
Copy link
Collaborator Author

@greptile

@waleedlatif1 waleedlatif1 merged commit 4f04b1e into staging Jan 14, 2026
10 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/console branch January 14, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants