Skip to content

Enhancement: createHistoryStore has no maxLength option — undo stack grows unbounded #1746

@palak170306-design

Description

@palak170306-design

Which package?

@termuijs/store

What happened?

createHistoryStore provides no mechanism to limit the size of the undo stack. The past[]
array grows indefinitely with every call to set():

timeline = {
    past: [...timeline.past, timeline.present], // unbounded growth
    present: newState,
    future: []
}

In long-running terminal applications — text editors, log viewers, interactive shells — this
causes continuous memory growth with no way to bound it.

A secondary issue: getHistory() returns a full structural clone of both past[] and
future[] on every call, even when the caller only needs to check if undo/redo is available.
There is no lightweight canUndo / canRedo boolean getter, so checking availability
requires a full O(n) clone.

Expected: The API should support capping history depth and provide cheap availability checks.
Actual: No maxLength option exists; checking availability requires cloning the full timeline.

Steps to reproduce

```typescript
import { createHistoryStore } from '@termuijs/store';

const store = createHistoryStore({ text: '' });

// Simulate a user typing 100,000 characters (one history entry per keystroke)
for (let i = 0; i < 100_000; i++) {
store.set({ text: 'a'.repeat(i + 1) });
}

const h = store.getHistory();
console.log(h.past.length); // 100,000 — all entries retained in memory forever
// Memory used by past[]: O(n²) because each entry stores incrementally longer strings
```

Proposed API addition:

```typescript
// createHistoryStore with optional maxLength
createHistoryStore(initialPresent, { maxLength: 100 })

// Lightweight availability checks (no clone)
store.canUndo // boolean
store.canRedo // boolean
```

When maxLength is set, the oldest entries in past[] are evicted (shift) when the limit
is exceeded — matching the behaviour of virtually every editor undo system.

Environment

  • TermUI version: latest (main branch)
  • Node.js 18+
  • Any OS / terminal

GSSoC contributor?

  • Yes. You contribute under GSSoC 2026.
  • No.

Metadata

Metadata

Labels

assignedIssue claimed by a contributor.type:feature+10 pts. New feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions