Skip to content

Fix objectLimit to cap total objects globally, not per type#212

Open
zeppnyc wants to merge 1 commit into
tscircuit:mainfrom
zeppnyc:fix/object-limit-global-cap
Open

Fix objectLimit to cap total objects globally, not per type#212
zeppnyc wants to merge 1 commit into
tscircuit:mainfrom
zeppnyc:fix/object-limit-global-cap

Conversation

@zeppnyc
Copy link
Copy Markdown

@zeppnyc zeppnyc commented May 13, 2026

Summary

Fixes the objectLimit prop on InteractiveGraphics so it caps the total number of rendered objects, instead of capping each object type bucket independently.

The bug

filterAndLimit in InteractiveGraphics.tsx applied slice(-objectLimit) to every object type bucket separately:

return objectLimit ? filtered.slice(-objectLimit) : filtered

There are 8 buckets (arrows, infiniteLines, lines, rects, polygons, circles, texts, points), so passing objectLimit={3} could still render up to 3 × 8 = 24 objects.

This contradicts both:

  • The issue spec: "limits the number of objects displayed (after filters) on InteractiveGraphics".
  • The existing red indicator UI: "Display limited to {objectLimit} objects. Received: {total}." — already assumes a single global cap.

Reproduces on the existing fixture examples/interactive-object-limit-layer-and-step-filtering.fixture.tsx: with objectLimit={3} and 7 objects in the graph (3 rects + 3 points + 1 circle), all 7 currently render while the red indicator says "Display limited to 3 objects. Received: 7.".

The fix

  • New pure helper site/utils/applyObjectLimit.ts distributes the limit globally across all object buckets, filling backwards from the last bucket in render order. This preserves the previous "last N" semantic from slice(-objectLimit) — the most recently added objects survive.
  • filterAndLimit no longer slices; the global limit is applied in a new limitedBuckets memo in InteractiveGraphics.tsx.
  • totalFilteredObjects now reports the true pre-limit total, so the isLimitReached indicator triggers exactly when the limit is actually capping output.
  • Render JSX reads from limitedBuckets instead of per-type filteredXxx memos.

Verification

  • bun test → 71 pass (62 baseline + 9 new unit tests for applyObjectLimit covering: no-limit, zero-limit, total-below-limit, single-bucket cap, multi-bucket budget fill, full-drop semantics, immutability, equality-to-total, and in-bucket order preservation)
  • bun run format:check → clean
  • bunx tsc --noEmit → clean

/claim #42

Previously, `filterAndLimit` applied `slice(-objectLimit)` to each
object type bucket independently (8 buckets: arrows, infiniteLines,
lines, rects, polygons, circles, texts, points), so a graph containing
N object types could display up to `N * objectLimit` objects.

This contradicted the issue spec ("limits the number of objects
displayed") and the existing "Display limited to X. Received: Y" UI
message, which already assumed a global cap.

Extract a pure `applyObjectLimit` helper that distributes the limit
across all object buckets, filling from the last bucket in render
order backwards (preserving the previous "last N" semantic from
`slice(-objectLimit)`). `totalFilteredObjects` now reports the true
pre-limit total so the `isLimitReached` indicator triggers correctly.

Refs tscircuit#42

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

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

Project Deployment Actions Updated (UTC)
graphics-debug Ready Ready Preview, Comment May 13, 2026 11:30am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant