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?
Which package?
@termuijs/store
What happened?
createHistoryStoreprovides no mechanism to limit the size of the undo stack. Thepast[]array grows indefinitely with every call to
set():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 bothpast[]andfuture[]on every call, even when the caller only needs to check if undo/redo is available.There is no lightweight
canUndo/canRedoboolean getter, so checking availabilityrequires a full O(n) clone.
Expected: The API should support capping history depth and provide cheap availability checks.
Actual: No
maxLengthoption 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
maxLengthis set, the oldest entries inpast[]are evicted (shift) when the limitis exceeded — matching the behaviour of virtually every editor undo system.
Environment
GSSoC contributor?