Skip to content

Bug: createHistoryStore uses Object.is for deduplication instead of structural equality #1742

@palak170306-design

Description

@palak170306-design

Which package?

@termuijs/store

What happened?

createHistoryStore uses Object.is to deduplicate consecutive identical states in set(),
but the JSDoc comment explicitly says the implementation uses JSON.stringify for structural equality:

"The implementation uses simple structural equality via JSON.stringify to avoid pushing
identical consecutive states."

The actual code on line 61 of history.ts:

if (Object.is(timeline.present, newState)) return;

Object.is is reference equality, not structural/value equality. For primitive types like
string and number, this coincidentally works — which is why all existing tests pass (they
use string state). But for any object or array state, two deeply-equal values with different
references always pass the check, causing a duplicate entry to be pushed into past[] on
every call to set().

Expected: set({ count: 0 }) called twice with the same content pushes one past entry.
Actual: Each call pushes a new entry — past[] grows even when state content is unchanged.

Steps to reproduce

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

const store = createHistoryStore({ count: 0 });

store.set({ count: 0 }); // different reference, identical content
store.set({ count: 0 }); // same again

const history = store.getHistory();
console.log(history.past.length);
// Logs: 2
// Expected: 0 — no change in value, so no history entry should be created
```

The dedup guard is supposed to prevent this, but Object.is on two { count: 0 } object
literals returns false because they are different references. The intended
JSON.stringify-based equality check from the JSDoc was never implemented.

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:bug+10 pts. Bug fix.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions