Skip to content

Conversation

@icecrasher321
Copy link
Collaborator

@icecrasher321 icecrasher321 commented Jan 27, 2026

Summary

Undo-Redo state maintained for code subblocks for better UX. Using Index DB for massive limit on num of stacks at once.

Type of Change

  • New feature

Testing

Tested with @Sg312

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 27, 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 27, 2026 3:22am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 27, 2026

Greptile Overview

Greptile Summary

Implemented undo-redo functionality for code blocks in function blocks, enabling users to revert and reapply code changes with standard keyboard shortcuts.

The implementation adds:

  • Debounced state tracking: Uses a 300ms debounce to batch rapid edits into single undo entries, avoiding cluttered history
  • IndexedDB persistence: Undo/redo stacks persist across browser sessions via idb-keyval
  • Collaborative conflict resolution: Automatically clears local undo history when remote users edit the same function code block
  • Keyboard shortcuts: Standard Cmd+Z (undo) and Cmd+Shift+Z/Cmd+Y (redo) support
  • Scoped to function blocks: Only enabled for blockType === 'function' and subBlockId === 'code'

The architecture separates concerns well:

  • useCodeUndoRedo hook manages debouncing, session lifecycle, and collaborative integration
  • useCodeUndoRedoStore Zustand store handles stack operations with LRU eviction (max 50 stacks, 500 entries each)
  • codeUndoRedoStorage provides async IndexedDB persistence layer

Key insight: The implementation uses isApplyingRef guard to prevent undo/redo operations from creating new history entries when applying previous states - preventing infinite loops.

Confidence Score: 4/5

  • This PR is safe to merge with one minor fix needed for the debounce timer cleanup
  • The implementation is well-architected with proper separation of concerns, collaborative workflow integration, and IndexedDB persistence. However, there's a missing cleanup effect for the debounce timer that could cause the timeout to fire after component unmount, potentially causing state updates on unmounted components. The fix is straightforward and the issue is unlikely to cause problems in practice, but it should be addressed.
  • Pay close attention to apps/sim/hooks/use-code-undo-redo.ts - add the cleanup effect for the debounce timer

Important Files Changed

Filename Overview
apps/sim/hooks/use-code-undo-redo.ts New hook implementing debounced undo-redo state management for code blocks with collaborative workflow integration
apps/sim/stores/undo-redo/code-store.ts Zustand store with IndexedDB persistence managing per-block undo/redo stacks with capacity limits and LRU eviction
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.tsx Integrated undo-redo hook with keyboard shortcuts (Cmd+Z/Cmd+Shift+Z), replacing manual edit tracking with debounced state recording

Sequence Diagram

sequenceDiagram
    participant User
    participant CodeEditor as Code Editor Component
    participant Hook as useCodeUndoRedo Hook
    participant Store as CodeUndoRedoStore
    participant IDB as IndexedDB
    participant Collab as Collaborative Workflow

    User->>CodeEditor: Types code
    CodeEditor->>Hook: recordChange(newValue)
    Hook->>Hook: Set pendingBefore (if first change)
    Hook->>Hook: Set pendingAfter
    Hook->>Hook: Start 300ms debounce timer
    
    Note over Hook: User continues typing...
    User->>CodeEditor: Types more
    CodeEditor->>Hook: recordChange(newerValue)
    Hook->>Hook: Clear previous timer
    Hook->>Hook: Update pendingAfter
    Hook->>Hook: Restart 300ms timer
    
    Note over Hook: Timer expires after 300ms of no edits
    Hook->>Store: push(entry with before/after)
    Store->>Store: Add to undo stack
    Store->>Store: Clear redo stack
    Store->>IDB: Persist state
    
    User->>CodeEditor: Press Cmd+Z
    CodeEditor->>Hook: undo()
    Hook->>Store: undo(workflowId, blockId, subBlockId)
    Store->>Store: Pop from undo stack
    Store->>Store: Push to redo stack
    Store-->>Hook: Return entry
    Hook->>Hook: applyValue(entry.before)
    Hook->>Collab: collaborativeSetSubblockValue()
    Collab->>CodeEditor: Update code value
    
    Note over User,Collab: Remote user edits same block
    Collab->>Store: clear(workflowId, blockId, subBlockId)
    Store->>Store: Delete undo/redo stacks
    Store->>IDB: Persist cleared state
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.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@icecrasher321
Copy link
Collaborator Author

@cursor review

@icecrasher321
Copy link
Collaborator Author

@cursor review

@icecrasher321
Copy link
Collaborator Author

@cursor review

@icecrasher321
Copy link
Collaborator Author

@cursor review

@icecrasher321
Copy link
Collaborator Author

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@icecrasher321 icecrasher321 merged commit 51891da into staging Jan 27, 2026
12 checks passed
@icecrasher321 icecrasher321 deleted the feat/code-undo-redo branch January 27, 2026 03:40
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