Skip to content

feat: S4 off-screen autosize columns#5

Merged
blove merged 10 commits into
mainfrom
feat/s4-off-screen-autosize
Apr 21, 2026
Merged

feat: S4 off-screen autosize columns#5
blove merged 10 commits into
mainfrom
feat/s4-off-screen-autosize

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented Apr 21, 2026

Summary

  • Add autosizeColumns() pure function in layout-core that computes optimal column widths from content using character-count heuristics (no DOM rendering)
  • Three-layer API: pure function → imperative store.autosizeColumns() → declarative autosize: boolean | AutosizeOptions option
  • Wire S4 scenario (25k rows × 200 cols) through bench infrastructure with passing E2E benchmark

Design

See docs/superpowers/specs/2026-04-21-off-screen-autosize-design.md

Test plan

  • 10 unit tests for pure autosizeColumns (content sizing, min/max clamp, header inclusion, emoji, getValue, empty rows)
  • 3 unit tests for grid-core store integration (declarative, custom options, imperative)
  • Query-state test for S4 scenario parsing
  • Bench-runner validation test updated for S4 support
  • S4 E2E benchmark passes (scroll script, dev scale)
  • S2 E2E regression passes
  • All 154 tests green, typecheck clean, lint clean

blove and others added 10 commits April 21, 2026 12:55
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Seven tasks covering layout-core pure function, grid-core integration,
public API surface, scenario-data changes, React wiring, and benchmark proof.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Estimates column widths from content using character-count heuristics.
Skips columns with explicit widthPx. Clamps to [minWidthPx, maxWidthPx].
Includes header text in width calculation.
GridCoreOptions gains autosize?: boolean | AutosizeOptions.
GridCoreStore gains autosizeColumns() imperative method.
Autosize runs on store creation when enabled, applying computed
widths as new column objects (no mutation of originals).
AutosizeOptions type and autosizeColumns() method are now
available through @pretable/core. PretableGrid.options now
delegates to gridCore.options to reflect autosized columns.
S4 columns no longer set widthPx, allowing autosize to compute
widths from content. Other scenarios keep explicit widths.
PretableSurface accepts autosize prop, passes through usePretableModel
to createGrid. Bench adapter enables autosize for S4 datasets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add S4 to the bench query state parser and scenario ID union so
the bench harness can run S4 benchmarks via URL params.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow the S4 off-screen autosize scenario to run through bench-runner
validation. Update test to use S6 as the unsupported scenario example.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@blove blove merged commit 2c20a9a into main Apr 21, 2026
4 of 5 checks passed
@blove blove deleted the feat/s4-off-screen-autosize branch May 1, 2026 17:32
blove added a commit that referenced this pull request May 10, 2026
B2 follow-up #5a (first slice of follow-up #5). The supportedScripts
gate in packages/bench-runner/src/index.ts kept scroll-with-format /
scroll-with-render / scroll-with-heavy-render pretable-only, even
though the AG Grid + TanStack + MUI adapters had wired the
scriptName-driven render branches in Phase 1-3 of B2.

Changes:

- `packages/bench-runner/src/index.ts`: split the gate. Cell-renderer
  scripts now run on all four adapters (S2-only); selection scripts
  (select-range-extend / keyboard-nav-row / select-all) remain
  pretable-only because range-select + select-all are paid-tier in
  AG Grid Enterprise + MUI X Pro and TanStack ships no native cell
  selection.
- `packages/bench-runner/src/__tests__/bench-runner.test.ts`: positive
  assertions that all four adapters can run cell-renderer scripts on
  S2; regression guard that selection scripts stay pretable-only.
- `apps/bench/src/bench-app.tsx`: cell-renderer scripts now get the
  same extra mount-frame wait that scroll already had — without it,
  AG Grid hit "scroll viewport unavailable" because its body viewport
  attaches one frame after the section becomes visible.

Matrix re-run committed under
status/milestones/2026-05-10-b2-cell-renderer-comparators.hypotheses.json
(4 adapters × 4 scripts × 3 repeats; ~2 min wall-clock). H1 + H19 +
H20 + H21 all satisfied.

Findings (n=3 medians, blank-gap counts in parens):

| Script | pretable | ag-grid | tanstack | mui |
| --- | --- | --- | --- | --- |
| scroll-with-format | 10.2ms (0) | 25.1ms (1) | 17.5ms (1) | 10.2ms (0) |
| scroll-with-render | 16.4ms (0) | 24.9ms (1) | 17.0ms (1) | 10.3ms (0) |
| scroll-with-heavy-render | 10.3ms (0) | 25.2ms (1) | 23.4ms (1) | 10.1ms (0) |

Pretable beats AG Grid 2-2.5× on every cell-renderer script with zero
blank gaps. Pretable matches MUI on format and heavy-render but loses
on scroll-with-render — anomaly logged for follow-up investigation
(pretable's cheap-React-cellRenderer path has a perf cliff that the
heavier path avoids).

H19/H20/H21 evaluators are pretable-only at the evaluator level; the
comparator data lives in per-run summary files. Future work could
extend the evaluators to surface comparator evidence inline.

Sort/filter gate (option C from the brainstorm) is the remaining slice
of follow-up #5, sequenced after this PR per "A then C".

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
blove added a commit that referenced this pull request May 10, 2026
* docs(plans): B2 follow-up #5b — sort + filter comparator wiring

Plan for the second slice of B2 follow-up #5: open the sort /
filter-metadata / filter-text gate for ag-grid + tanstack + mui, wire
library-native sort + filter dispatch in each adapter, re-run the
matrix to capture comparator data for H6/H7/H8.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(bench-runner): open sort/filter scripts to comparator adapters

Drop the pretable-only gate on sort/filter-metadata/filter-text — all
four bench adapters now wire their native sort/filter API. The
scenario gate (S2/S7 only) remains.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(bench): AG Grid adapter applies BenchInteractionPlan via applyColumnState + setFilterModel

Wire the interactionPlan prop into the AG Grid adapter so the bench
harness can drive sort/filter via the library's native gridApi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(bench): TanStack adapter applies BenchInteractionPlan via setSorting + setColumnFilters

Capture the Table instance in a ref synced each render so a useEffect
can drive sort/filter via TanStack's library-native API. filter-metadata
mode uses the equalsString filterFn to match the bench plan's equals
semantics.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(bench): MUI adapter applies BenchInteractionPlan via apiRef.setSortModel + setFilterModel

Wire the interactionPlan prop into the MUI adapter so the bench
harness can drive sort/filter via the library-native apiRef.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(bench): dispatch interaction scripts to comparator adapters

Drop the pretable-only gate around measureBenchInteractionRun. All
four adapters now run sort + filter through the interaction probe.
Telemetry-based state reading remains pretable-only; comparators
fall back to DOM-default state reading (undefined override).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(research): B2 follow-up #5b — sort + filter comparator wiring evidence

Append the 2026-05-10 entry covering the gate-opening + per-adapter
wiring, n=3 latency table, and H6/H7/H8 status delta. Ship the matrix
re-run milestone alongside.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
blove added a commit that referenced this pull request May 11, 2026
…5 cross-validation

PR #128's S5/S7 cross-validation matrix surfaced a finding: AG Grid
Community matches pretable on every measured streaming numeric (frame
p95, 25k/sec envelope, visible-row drift). The homepage's stub-era
"purpose-built streaming pipeline" framing — and the implication that
pretable is uniquely fast at streaming — is no longer supportable on
hypothesis-scale numerics. The honest wedge is package surface:
pretable ships the SSE → partial-JSON → batcher → applyTransaction
pipeline as a single import; AG Grid expects you to wire it yourself.

Three editorial edits:

- ComparisonTable.tsx: streaming row renamed from "purpose-built
  streaming pipeline" to "streaming pipeline (SSE → partial JSON →
  batcher → applyTransaction)" — same yes/n/a/n/a/n/a shape, sharper
  capability claim. Header docblock updated to cite the S5/S7
  cross-validation milestone alongside the existing B2 sources.

- ReceiptsBand.tsx: replaced the "25k/s · max sustained update rate"
  hero stat (no longer pretable-unique) with "OpenAI · Anthropic · SSE
  · streaming sources, one import". Added a `compact: true` flag to
  the Stat interface so the longer label renders at 20–24 px instead
  of 44–56 px, preserving the four-cell grid without overflowing the
  hero font scale.

- FeatureGrid.tsx: Stream-aware card — dropped "sustained from 100 to
  25,000 updates/sec" tail; rewrote the description around the pipeline
  that ships as one import.

Test added: ReceiptsBand.test.tsx regression-guards the new capability
anchor (`streaming sources` + `openai`).

Repo-memory entry appended (B2 follow-up #7); MEMORY.md index updated;
project_b2_followups.md regenerated to reflect everything resolved
except item #5 (open comparator interaction scripts).

No source/package changes outside apps/website + the docs entry; all
190+ website tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
blove added a commit that referenced this pull request May 11, 2026
…5 cross-validation (#129)

PR #128's S5/S7 cross-validation matrix surfaced a finding: AG Grid
Community matches pretable on every measured streaming numeric (frame
p95, 25k/sec envelope, visible-row drift). The homepage's stub-era
"purpose-built streaming pipeline" framing — and the implication that
pretable is uniquely fast at streaming — is no longer supportable on
hypothesis-scale numerics. The honest wedge is package surface:
pretable ships the SSE → partial-JSON → batcher → applyTransaction
pipeline as a single import; AG Grid expects you to wire it yourself.

Three editorial edits:

- ComparisonTable.tsx: streaming row renamed from "purpose-built
  streaming pipeline" to "streaming pipeline (SSE → partial JSON →
  batcher → applyTransaction)" — same yes/n/a/n/a/n/a shape, sharper
  capability claim. Header docblock updated to cite the S5/S7
  cross-validation milestone alongside the existing B2 sources.

- ReceiptsBand.tsx: replaced the "25k/s · max sustained update rate"
  hero stat (no longer pretable-unique) with "OpenAI · Anthropic · SSE
  · streaming sources, one import". Added a `compact: true` flag to
  the Stat interface so the longer label renders at 20–24 px instead
  of 44–56 px, preserving the four-cell grid without overflowing the
  hero font scale.

- FeatureGrid.tsx: Stream-aware card — dropped "sustained from 100 to
  25,000 updates/sec" tail; rewrote the description around the pipeline
  that ships as one import.

Test added: ReceiptsBand.test.tsx regression-guards the new capability
anchor (`streaming sources` + `openai`).

Repo-memory entry appended (B2 follow-up #7); MEMORY.md index updated;
project_b2_followups.md regenerated to reflect everything resolved
except item #5 (open comparator interaction scripts).

No source/package changes outside apps/website + the docs entry; all
190+ website tests pass.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant