From 7631fc3d2ca725251a9f0beccfbcceac9faf520e Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 09:34:04 -0700 Subject: [PATCH 01/11] =?UTF-8?q?docs(spec):=20tier=201=20sub-project=20A?= =?UTF-8?q?=20=E2=80=94=20PR=202=20(@pretable/core=20audit)=20design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames GridCore* → Pretable* at source in @pretable-internal/grid-core and layout-core; collapses @pretable/core's types.ts; replaces PretableGrid's Omit<> leak with an explicit interface; bundledPackages update so api-extractor inlines the renamed types in core.api.md. Headless docs/examples are explicitly deferred per memory. Co-Authored-By: Claude Opus 4.7 --- ...tier1-api-stabilization-pr2-core-design.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md diff --git a/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md new file mode 100644 index 000000000..e9bb29a8b --- /dev/null +++ b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md @@ -0,0 +1,184 @@ +# Tier 1 Sub-project A — PR 2 (`@pretable/core` audit) Design + +> Status: spec. 2026-05-08. PR 2 of 5 in [Tier 1 Sub-project A — Public API Stabilization](2026-05-07-tier1-public-api-stabilization-design.md). + +## Goal + +Lock `@pretable/core`'s public surface into a state appropriate for a future headless engine (long-term scope) while shipping only the type cleanup now (no docs/examples — that's deferred per `project_headless_engine_docs_deferred.md` memory). Eliminate the `GridCore*` naming leakage by renaming the engine-level types at source and re-exporting them under their natural `Pretable*` names. + +## Non-goals + +- No `@pretable/react` audit. PR 3 owns react's surface; this PR only touches react where the rename forces a mechanical import update. +- No headless-mode website docs, no `apps/headless-demo`, no `examples/headless-*` content. Deferred per memory. +- No `@pretable-internal/grid-core` package consolidation into `@pretable/core`. Engine package stays separate. +- No new tests beyond rename ripple. Existing tests cover behavior; the audit is type-level. + +## Architecture + +### Public-surface layout + +`@pretable/core/src/` becomes: + +``` +src/ + index.ts // export * from './public_api'; + public_api.ts // hand-curated re-exports, TSDoc + @public on each + types.ts // re-exports from @pretable-internal/grid-core + create-grid.ts // unchanged +``` + +`public_api.ts` is the only file whose contents are reviewed for public-API impact. `index.ts` is one line. + +### Engine type rename (the structural change) + +`@pretable-internal/grid-core` is the underlying engine; today its types use `GridCore*` naming and `@pretable/core` aliases them with `Pretable*` names. Aliasing creates `ae-forgotten-export` warnings and leaks the internal name through `extends` clauses. + +**Resolution:** rename the engine types at source. The engine becomes `Pretable*`-named in `@pretable-internal/grid-core`'s own `src/types.ts`. `@pretable/core/types.ts` collapses from ~50 lines of aliases to a clean re-export shell. + +`@pretable-internal/grid-core` and `@pretable-internal/layout-core` are added to `bundledPackages` in `api-extractor.base.json` so the renamed types appear inlined in `core.api.md` rather than as `import { … } from '@pretable-internal/…'` references. Each `.api.md` stays self-contained. + +### `PretableGrid` interface + +The current `PretableGrid extends Omit, "options">` is replaced with an explicit interface in `@pretable/core` that lists every method/property pretable promises. After rename, `GridCoreStore` becomes `PretableEngine` at the engine source — but `PretableGrid` becomes a *new, narrower* interface in `@pretable/core` that `createGrid` returns. The internal engine factory (`createGridCore`) returns `PretableEngine`; `createGrid` wraps/casts to the public `PretableGrid`. + +The rationale: `Omit<>` inheritance leaks the engine type into the public surface and forces every `.api.md` reader to mentally subtract a key. An explicit interface is what users will read in IDE tooltips. + +## Components + +### Rename map + +In `@pretable-internal/grid-core/src/types.ts` and `create-grid-core.ts`: + +| Internal (today) | After rename | Notes | +|---|---|---| +| `GridCoreCellAddress` | `PretableCellAddress` | Already aliased — absorb. | +| `GridCoreCellRange` | `PretableCellRange` | Already aliased — absorb. | +| `GridCoreColumn` | `PretableColumn` | Was `PretableCoreColumn`. React imports as `PretableBaseColumn` to disambiguate from its own `PretableColumn`. PR 3 fully resolves the naming. | +| `GridCoreFocusDirection` | `PretableFocusDirection` | Already aliased — absorb. | +| `GridCoreFocusState` | `PretableFocusState` | Already aliased — absorb. | +| `GridCoreFormatInput` | `PretableFormatInput` | Was an alias — absorb. | +| `GridCoreMoveFocusOptions` | `PretableMoveFocusOptions` | Already aliased — absorb. | +| `GridCoreOptions` | `PretableGridOptions` | Was an alias — absorb. | +| `GridCoreRow` | `PretableRow` | Was a `Record` constraint; `PretableRow` already exists in `@pretable/core/types.ts`. Unify on the public name. | +| `GridCoreRowModel` | `PretableVisibleRow` | Already aliased — absorb. | +| `GridCoreSelectionState` | `PretableSelectionState` | Already aliased — absorb. | +| `GridCoreSnapshot` | `PretableGridSnapshot` | Already aliased — absorb. | +| `GridCoreSortDirection` | `PretableSortDirection` | Already aliased — absorb. | +| `GridCoreSortState` | `PretableSortState` | Already aliased — absorb. | +| `GridCoreStore` | `PretableEngine` | Internal engine handle returned by `createGridCore`. Distinct from public `PretableGrid` (see Architecture). | +| `GridCoreTransaction` | `PretableTransaction` | Was an alias — absorb. | +| `GridCoreViewportState` | `PretableViewportState` | Already aliased — absorb. | +| `RowSelectionTriState` | `PretableRowSelectionTriState` | Already aliased — absorb. | + +In `@pretable-internal/layout-core/src/types.ts`: + +| Internal (today) | After rename | Notes | +|---|---|---| +| `LayoutSpan` | `PretableRowRange` | Semantic name — it represents the visible-row index range exposed via `PretableGridSnapshot.visibleRange`. | + +`AutosizeOptions` keeps its name (already pretable-friendly). + +### `@pretable/core` public surface (post-rename) + +`public_api.ts` re-exports, every symbol carrying `@public` + a one-line TSDoc summary: + +``` +export { createGrid } from "./create-grid"; +export type { PretableGrid } from "./pretable-grid"; +export type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableRowRange, + PretableRowSelectionTriState, + PretableSelectionState, + PretableSortDirection, + PretableSortState, + PretableTransaction, + PretableViewportState, + PretableVisibleRow, +} from "./types"; +``` + +`pretable-grid.ts` is the new file holding the explicit `PretableGrid` interface — defined locally, not re-exported from the engine. (`@pretable-internal/grid-core`'s engine handle is the renamed `PretableEngine`, separate from public `PretableGrid`.) `types.ts` does not re-export `PretableGrid`. + +### TSDoc style + +- One-line summary above every symbol. +- `@example` blocks **only** for `createGrid` and the new `PretableGrid` interface. +- Type aliases get one-line summaries; no examples. + +### `ae-missing-release-tag` config + +PR 1 set this rule's `logLevel` to `none` to allow undocumented baselines. PR 2 flips it to `warning` once core is fully tagged. The `warning` level surfaces coverage gaps (a developer adds a public symbol but forgets the `@public` tag) without blocking CI in non-local mode. (api-extractor's non-local mode treats configured-as-error issues as fatal but allows warnings; the `warning` level produces visibility, not enforcement.) + +## Data flow + +1. Author renames at engine source (`@pretable-internal/{grid-core,layout-core}`). +2. Internal consumers (`@pretable-internal/renderer-dom`, `@pretable/react/src/types.ts`'s import alias) updated. +3. `@pretable/core/types.ts` collapses to clean re-exports. +4. New `@pretable/core/src/pretable-grid.ts` defines the explicit `PretableGrid` interface. +5. `public_api.ts` re-exports with TSDoc. +6. `api-extractor.base.json` updates `bundledPackages` to include the two internal packages. +7. `pnpm api` regenerates `core.api.md` (large diff: zero `ae-forgotten-export` warnings, type aliases now show `@public` documented entries). +8. `react.api.md` regenerated as a side effect of the rename + bundledPackages change. Verify the diff is mechanical (renames only, no shape change). + +## Error handling + +This PR's failure modes are tooling and process: + +- **Internal compile errors after rename.** Caught by `pnpm -w typecheck`. The audit fixes them inline. +- **`react.api.md` drifts unexpectedly.** PR's job to verify the drift is rename-only; if shapes change, regress. +- **`ae-missing-release-tag` warnings remain in `core.api.md`.** Means a symbol slipped past tagging. Fix during the audit, not after. +- **CI fails because `pnpm api:check` mismatches.** Run `pnpm api`, commit, retry. + +## Testing + +Repo-wide gates: `pnpm -w typecheck`, `pnpm -w test`, `pnpm -w lint`, `pnpm format`, `pnpm api:check`. + +No new test categories. Existing test coverage already exercises the renamed types under their old names; renames cascade through fine. The single test file under `packages/grid-core/src/__tests__/selection-state.test.ts` that imports `GridCore*` types directly gets a mechanical update. + +## Per-package README + +`packages/core/README.md` ~80 lines: + +- One-paragraph "what is `@pretable/core`" — the headless engine. Most users reach for `@pretable/react`; this package exists for users who want to drive their own UI from the engine state. +- "When to use" — 2-3 sentences. Mention that headless usage is supported but full docs/examples/demos are forthcoming (links to the deferred-memory's "future task triggers" framing without naming the memory). +- Install command and minimal `createGrid` example. +- "See [`core.api.md`](./core.api.md) for the full public surface." +- License/contributing footer matching repo style. + +## PR shape + +Single PR. The rename is mechanical and atomic — splitting would force `@pretable/react` to compile against half-renamed engine types, an unstable intermediate state. + +Implementation tasks (subagent-driven): + +1. Rename `LayoutSpan` → `PretableRowRange` in `@pretable-internal/layout-core` + update internal consumers. +2. Rename `GridCore*` → `Pretable*` in `@pretable-internal/grid-core` + update internal consumers (including the test file). +3. Update `@pretable-internal/renderer-dom` imports. +4. Update `@pretable/react/src/types.ts` import (alias `PretableColumn as PretableBaseColumn`). +5. Define explicit `PretableGrid` interface in `@pretable/core/src/pretable-grid.ts`; rewrite `create-grid.ts` to return it. +6. Write `@pretable/core/src/public_api.ts` with TSDoc + `@public` tags; collapse `index.ts` to one line; collapse `types.ts` to clean re-exports. +7. Add `@pretable-internal/grid-core` and `@pretable-internal/layout-core` to `bundledPackages` in `api-extractor.base.json`. Flip `ae-missing-release-tag` to `warning`. +8. Regenerate `core.api.md` and `react.api.md`; verify react's diff is rename-only. +9. Write `packages/core/README.md`. +10. Repo-wide gates + PR. + +## Success criteria + +- `core.api.md` has zero `ae-forgotten-export` warnings. +- Every public symbol in `core.api.md` shows `@public` (not `@public (undocumented)`). +- `PretableGrid` is an explicit interface, not `extends Omit<…>`. +- `@pretable-internal/grid-core/src/types.ts` and `@pretable-internal/layout-core/src/types.ts` use only `Pretable*` names. +- `react.api.md` diff is mechanical rename only (no shape change). +- `packages/core/README.md` exists with the structure above. +- All repo-wide gates pass including `pnpm api:check`. From 9fc4382cfd444da6ee844d4e21691babdc5d3352 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 09:57:08 -0700 Subject: [PATCH 02/11] =?UTF-8?q?docs(plan):=20tier=201=20sub-project=20A?= =?UTF-8?q?=20=E2=80=94=20PR=202=20(core=20audit)=20implementation=20plan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 9 tasks: layout-core rename, grid-core rename (+ renderer-dom), explicit PretableGrid interface, react import update, public_api.ts with TSDoc + @public, api-extractor config update, regenerate .api.md files, README, gates+PR. Co-Authored-By: Claude Opus 4.7 --- ...-05-08-tier1-api-stabilization-pr2-core.md | 1095 +++++++++++++++++ 1 file changed, 1095 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md diff --git a/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md b/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md new file mode 100644 index 000000000..49aaad780 --- /dev/null +++ b/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md @@ -0,0 +1,1095 @@ +# Tier 1 Sub-project A — PR 2 (`@pretable/core` audit) Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Rename engine types at source so `@pretable/core`'s public surface uses natural `Pretable*` names instead of `GridCore*` aliases; replace `PretableGrid`'s `Omit<>` leak with an explicit interface; tag every public symbol with TSDoc + `@public`; ship a per-package README. + +**Architecture:** Three rename waves (`@pretable-internal/layout-core`, then `@pretable-internal/grid-core`, then `@pretable/core` and its consumers in `@pretable/react`), one new file (`pretable-grid.ts`) holding the explicit `PretableGrid` interface, one new file (`public_api.ts`) holding the curated public re-exports with TSDoc, one config update to `api-extractor.base.json`, and one new README. After the rename, `core.api.md` regenerates with no `ae-forgotten-export` warnings and every symbol carries `@public`. + +**Tech Stack:** TypeScript (workspace-wide rename), `@microsoft/api-extractor`, `@microsoft/tsdoc`, pnpm workspaces. + +**Source spec:** `docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md` + +--- + +## File Structure + +| Path | Responsibility | Action | +|---|---|---| +| `packages/layout-core/src/types.ts` | `LayoutSpan` interface | Modify (rename → `PretableRowRange`) | +| `packages/layout-core/src/index.ts` | Layout-core barrel | Modify (rename in re-export) | +| `packages/grid-core/src/types.ts` | All `GridCore*` types | Modify (rename → `Pretable*`) | +| `packages/grid-core/src/index.ts` | Grid-core barrel | Modify (rename in re-exports) | +| `packages/grid-core/src/create-grid-core.ts` | Engine factory | Modify (rename internal references) | +| `packages/grid-core/src/derived-rows.ts` | Internal helper | Modify (rename internal references) | +| `packages/grid-core/src/derived-selection.ts` | Internal helper | Modify (rename `RowSelectionTriState` → `PretableRowSelectionTriState`) | +| `packages/grid-core/src/__tests__/selection-state.test.ts` | Test file | Modify (rename imports) | +| `packages/renderer-dom/src/types.ts` | DOM render types | Modify (rename internal imports) | +| `packages/renderer-dom/src/create-renderer.ts` | DOM renderer | Modify (rename internal imports) | +| `packages/core/src/pretable-grid.ts` | **NEW** explicit `PretableGrid` interface | Create | +| `packages/core/src/types.ts` | Re-export shell | Modify (collapse from ~50 lines to ~25) | +| `packages/core/src/create-grid.ts` | `createGrid` factory | Modify (return type uses local `PretableGrid`) | +| `packages/core/src/public_api.ts` | **NEW** curated public surface with TSDoc | Create | +| `packages/core/src/index.ts` | Package entry | Modify (collapse to `export * from './public_api'`) | +| `packages/react/src/types.ts` | React's column/render types | Modify (rename import alias) | +| `packages/react/src/index.ts` | React barrel | Modify (rename one re-export) | +| `api-extractor.base.json` | api-extractor config | Modify (`bundledPackages` + `ae-missing-release-tag`) | +| `packages/core/core.api.md` | Generated baseline | Regenerate | +| `packages/react/react.api.md` | Generated baseline | Regenerate (rename-only diff expected) | +| `packages/core/README.md` | **NEW** per-package README | Create | + +--- + +## Task 1: Rename `LayoutSpan` → `PretableRowRange` in `@pretable-internal/layout-core` + +**Files:** +- Modify: `packages/layout-core/src/types.ts` +- Modify: `packages/layout-core/src/index.ts` +- Modify: `packages/grid-core/src/types.ts` (consumer) +- Modify: `packages/grid-core/src/derived-rows.ts` (consumer, if it imports `LayoutSpan`) + +- [ ] **Step 1: Rename the interface in `packages/layout-core/src/types.ts`** + +Change line 1-4 from: +```ts +export interface LayoutSpan { + start: number; + end: number; +} +``` +to: +```ts +/** + * Half-open row index range — `start` inclusive, `end` exclusive — used to + * describe the visible row window in {@link PretableGridSnapshot.visibleRange}. + * + * @public + */ +export interface PretableRowRange { + start: number; + end: number; +} +``` + +Find every other occurrence of `LayoutSpan` in this file (line 42 references it inside `ViewportPlan`) and rename to `PretableRowRange`. + +- [ ] **Step 2: Update the barrel in `packages/layout-core/src/index.ts`** + +Find the line `LayoutSpan,` inside the `export type` list and rename to `PretableRowRange,`. + +- [ ] **Step 3: Update grid-core consumers** + +In `packages/grid-core/src/types.ts`, line 1-4 currently: +```ts +import type { + AutosizeOptions, + LayoutSpan, +} from "@pretable-internal/layout-core"; +``` +becomes: +```ts +import type { + AutosizeOptions, + PretableRowRange, +} from "@pretable-internal/layout-core"; +``` + +Then find the `visibleRange: LayoutSpan;` field (line 93) and rename to `visibleRange: PretableRowRange;`. + +Run `grep -n LayoutSpan packages/grid-core/src/derived-rows.ts` — if any matches appear, rename them similarly. + +- [ ] **Step 4: Verify typecheck** + +```bash +pnpm --filter @pretable-internal/layout-core typecheck && \ +pnpm --filter @pretable-internal/grid-core typecheck +``` + +Expected: both pass with no errors. + +- [ ] **Step 5: Verify no stale `LayoutSpan` references in source** + +```bash +grep -rn "LayoutSpan" packages 2>/dev/null | grep -v ".api.md\|/dist/" || echo "clean" +``` + +Expected: prints `clean` (nothing matches). + +- [ ] **Step 6: Commit** + +```bash +git add packages/layout-core/src packages/grid-core/src/types.ts packages/grid-core/src/derived-rows.ts +git commit -m "refactor(layout-core): rename LayoutSpan → PretableRowRange + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 2: Rename `GridCore*` → `Pretable*` at engine source + +**Files:** +- Modify: `packages/grid-core/src/types.ts` +- Modify: `packages/grid-core/src/index.ts` +- Modify: `packages/grid-core/src/create-grid-core.ts` +- Modify: `packages/grid-core/src/derived-rows.ts` +- Modify: `packages/grid-core/src/derived-selection.ts` +- Modify: `packages/grid-core/src/__tests__/selection-state.test.ts` +- Modify: `packages/renderer-dom/src/types.ts` +- Modify: `packages/renderer-dom/src/create-renderer.ts` + +- [ ] **Step 1: Rename interface/type declarations in `packages/grid-core/src/types.ts`** + +Apply this exact rename map across the file (using `sed` or editor batch-replace, then re-read to verify): + +``` +GridCoreCellAddress → PretableCellAddress +GridCoreCellRange → PretableCellRange +GridCoreColumn → PretableColumn +GridCoreFocusDirection → PretableFocusDirection +GridCoreFocusState → PretableFocusState +GridCoreFormatInput → PretableFormatInput +GridCoreFrame → PretableFrame +GridCoreMoveFocusOptions → PretableMoveFocusOptions +GridCoreOptions → PretableGridOptions +GridCoreRow → PretableRow +GridCoreRowModel → PretableVisibleRow +GridCoreSelectionState → PretableSelectionState +GridCoreSnapshot → PretableGridSnapshot +GridCoreSortDirection → PretableSortDirection +GridCoreSortState → PretableSortState +GridCoreStore → PretableEngine +GridCoreTransaction → PretableTransaction +GridCoreViewportState → PretableViewportState +``` + +A safe one-shot using `sed` (run from worktree root): + +```bash +files=( + packages/grid-core/src/types.ts + packages/grid-core/src/index.ts + packages/grid-core/src/create-grid-core.ts + packages/grid-core/src/derived-rows.ts + packages/grid-core/src/derived-selection.ts + packages/grid-core/src/__tests__/selection-state.test.ts + packages/renderer-dom/src/types.ts + packages/renderer-dom/src/create-renderer.ts +) +for f in "${files[@]}"; do + sed -i '' \ + -e 's/GridCoreCellAddress/PretableCellAddress/g' \ + -e 's/GridCoreCellRange/PretableCellRange/g' \ + -e 's/GridCoreFocusDirection/PretableFocusDirection/g' \ + -e 's/GridCoreFocusState/PretableFocusState/g' \ + -e 's/GridCoreFormatInput/PretableFormatInput/g' \ + -e 's/GridCoreFrame/PretableFrame/g' \ + -e 's/GridCoreMoveFocusOptions/PretableMoveFocusOptions/g' \ + -e 's/GridCoreOptions/PretableGridOptions/g' \ + -e 's/GridCoreRowModel/PretableVisibleRow/g' \ + -e 's/GridCoreSelectionState/PretableSelectionState/g' \ + -e 's/GridCoreSnapshot/PretableGridSnapshot/g' \ + -e 's/GridCoreSortDirection/PretableSortDirection/g' \ + -e 's/GridCoreSortState/PretableSortState/g' \ + -e 's/GridCoreStore/PretableEngine/g' \ + -e 's/GridCoreTransaction/PretableTransaction/g' \ + -e 's/GridCoreViewportState/PretableViewportState/g' \ + -e 's/GridCoreColumn/PretableColumn/g' \ + -e 's/GridCoreRow/PretableRow/g' \ + "$f" +done +``` + +Important: the order matters — `GridCoreColumn` must come **after** `GridCoreColumn`-prefix-disambiguating renames (none here), and `GridCoreRow` (substring of `GridCoreRowModel`) must come **after** `GridCoreRowModel`. The sed list above respects that. + +- [ ] **Step 2: Rename `RowSelectionTriState` → `PretableRowSelectionTriState`** + +In `packages/grid-core/src/derived-selection.ts`, find the export and the type usages: + +```bash +sed -i '' 's/RowSelectionTriState/PretableRowSelectionTriState/g' packages/grid-core/src/derived-selection.ts packages/grid-core/src/index.ts +``` + +- [ ] **Step 3: Verify no stale `GridCore` references remain** + +```bash +grep -rn "GridCore[A-Z]" packages 2>/dev/null | grep -v ".api.md\|/dist/\|node_modules" || echo "clean" +``` + +Expected: `clean`. + +```bash +grep -rn "\bRowSelectionTriState\b" packages 2>/dev/null | grep -v ".api.md\|/dist/\|PretableRowSelectionTriState" || echo "clean" +``` + +Expected: `clean`. + +- [ ] **Step 4: Verify typecheck and tests in the affected packages** + +```bash +pnpm --filter @pretable-internal/grid-core typecheck && \ +pnpm --filter @pretable-internal/grid-core test && \ +pnpm --filter @pretable-internal/renderer-dom typecheck +``` + +Expected: typechecks pass, grid-core tests still pass. + +- [ ] **Step 5: Commit** + +```bash +git add packages/grid-core/src packages/renderer-dom/src +git commit -m "refactor(grid-core): rename GridCore* → Pretable* at source + +Engine-level types now use Pretable* names directly. Internal-only +GridCoreStore renamed to PretableEngine to distinguish from the public +PretableGrid interface (defined separately in @pretable/core). + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 3: Define explicit `PretableGrid` in `@pretable/core`; rewrite `create-grid.ts`; collapse `types.ts` + +**Files:** +- Create: `packages/core/src/pretable-grid.ts` +- Modify: `packages/core/src/types.ts` +- Modify: `packages/core/src/create-grid.ts` + +- [ ] **Step 1: Create `packages/core/src/pretable-grid.ts` with the explicit interface** + +```ts +import type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableSelectionState, + PretableSortDirection, + PretableTransaction, + PretableViewportState, +} from "@pretable-internal/grid-core"; + +/** + * Public handle returned by {@link createGrid}. Exposes every action and + * observation pretable promises to support; does not extend the internal + * engine type, so private methods cannot leak through the public surface. + * + * @public + */ +export interface PretableGrid { + /** Discriminator — distinguishes `PretableGrid` from arbitrary objects. */ + readonly kind: "pretable-grid"; + + /** The options the grid was constructed with. */ + readonly options: PretableGridOptions; + + /** Subscribe to grid mutations. Returns an unsubscribe function. */ + subscribe(listener: () => void): () => void; + + /** Read the current snapshot. Stable reference until the next mutation. */ + getSnapshot(): PretableGridSnapshot; + + // sort / filter + setSort(columnId: string | null, direction: PretableSortDirection): void; + setFilter(columnId: string, value: string): void; + clearFilters(): void; + replaceFilters(nextFilters: Record): void; + + // selection + setSelection(state: PretableSelectionState): void; + selectAll(): void; + clearSelection(): void; + addRange(range: PretableCellRange): void; + extendRangeFromAnchor(addr: PretableCellAddress): void; + toggleRowSelection(rowId: string): void; + setSelectAllVisible(checked: boolean): void; + + // focus + setFocus(addr: PretableCellAddress | null): void; + moveFocus( + direction: PretableFocusDirection, + options?: PretableMoveFocusOptions, + ): void; + + // viewport + setViewport(viewport: PretableViewportState): void; + + // column layout + autosizeColumns(options?: AutosizeOptions): void; + setColumnWidth(columnId: string, width: number): void; + moveColumn(columnId: string, toIndex: number): void; + setColumnPinned(columnId: string, pinned: "left" | null): void; + autosizeColumn(columnId: string, options?: AutosizeOptions): void; + resetColumnLayout(): void; + mergeColumnsFromProps(nextColumns: PretableColumn[]): void; + + // streaming + applyTransaction(transaction: PretableTransaction): void; +} +``` + +- [ ] **Step 2: Replace `packages/core/src/types.ts` with a clean re-export shell** + +Overwrite the file with this content (collapses ~50 lines of aliases down to direct re-exports — the engine package now uses these names natively): + +```ts +export type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableRowSelectionTriState, + PretableSelectionState, + PretableSortDirection, + PretableSortState, + PretableTransaction, + PretableViewportState, + PretableVisibleRow, +} from "@pretable-internal/grid-core"; + +export type { PretableRowRange } from "@pretable-internal/layout-core"; +``` + +Note: `PretableGrid` is not re-exported from here — it is defined in `pretable-grid.ts`. `PretableEngine` is intentionally not re-exported either — it's an internal engine type. + +- [ ] **Step 3: Rewrite `packages/core/src/create-grid.ts`** + +Overwrite with: + +```ts +import { createGridCore } from "@pretable-internal/grid-core"; + +import type { PretableGrid } from "./pretable-grid"; +import type { PretableGridOptions, PretableRow } from "./types"; + +/** + * Create a pretable grid instance. Returns a {@link PretableGrid} handle + * that exposes every action and observation pretable supports. + * + * @example + * ```ts + * const grid = createGrid({ + * columns: [{ id: "name" }, { id: "age" }], + * rows: [{ id: "1", name: "Ada", age: 36 }], + * }); + * grid.setSort("age", "desc"); + * const snapshot = grid.getSnapshot(); + * ``` + * + * @public + */ +export function createGrid( + options: PretableGridOptions, +): PretableGrid { + const engine = createGridCore(options); + + return { + kind: "pretable-grid", + get options() { + return engine.options; + }, + subscribe: engine.subscribe, + getSnapshot: engine.getSnapshot, + setSort: engine.setSort, + setFilter: engine.setFilter, + clearFilters: engine.clearFilters, + replaceFilters: engine.replaceFilters, + setSelection: engine.setSelection, + selectAll: engine.selectAll, + clearSelection: engine.clearSelection, + addRange: engine.addRange, + extendRangeFromAnchor: engine.extendRangeFromAnchor, + toggleRowSelection: engine.toggleRowSelection, + setSelectAllVisible: engine.setSelectAllVisible, + setFocus: engine.setFocus, + moveFocus: engine.moveFocus, + setViewport: engine.setViewport, + autosizeColumns: engine.autosizeColumns, + setColumnWidth: engine.setColumnWidth, + moveColumn: engine.moveColumn, + setColumnPinned: engine.setColumnPinned, + autosizeColumn: engine.autosizeColumn, + resetColumnLayout: engine.resetColumnLayout, + mergeColumnsFromProps: engine.mergeColumnsFromProps, + applyTransaction: engine.applyTransaction, + }; +} +``` + +- [ ] **Step 4: Verify typecheck** + +```bash +pnpm --filter @pretable/core typecheck +``` + +Expected: passes. (At this point `@pretable/react` is broken because it imports `PretableCoreColumn`, fixed in Task 4.) + +- [ ] **Step 5: Commit** + +```bash +git add packages/core/src/pretable-grid.ts packages/core/src/types.ts packages/core/src/create-grid.ts +git commit -m "refactor(core): explicit PretableGrid interface; collapse types.ts + +Replaces extends Omit, 'options'> with an explicit +interface listing every method/property pretable promises. types.ts +becomes a re-export shell from the renamed engine types. + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 4: Update `@pretable/react` import alias and re-export + +**Files:** +- Modify: `packages/react/src/types.ts` +- Modify: `packages/react/src/index.ts` + +- [ ] **Step 1: Update import in `packages/react/src/types.ts`** + +Change lines 1-7 from: +```ts +import type { ReactNode } from "react"; +import type { + PretableCoreColumn, + PretableFormatInput, + PretableRow, +} from "@pretable/core"; +``` +to: +```ts +import type { ReactNode } from "react"; +import type { + PretableColumn as PretableBaseColumn, + PretableFormatInput, + PretableRow, +} from "@pretable/core"; +``` + +Then update the `extends` clause — find: +```ts +export interface PretableColumn< + TRow extends PretableRow = PretableRow, +> extends PretableCoreColumn { +``` +and change `extends PretableCoreColumn` to `extends PretableBaseColumn`. + +- [ ] **Step 2: Update re-export in `packages/react/src/index.ts`** + +Find the block (around lines 47-53): +```ts +// Re-exports from @pretable/core +export type { + PretableCoreColumn, + PretableGrid, + PretableGridOptions, + PretableGridSnapshot, + PretableRow, +} from "@pretable/core"; +``` +and change `PretableCoreColumn,` to `PretableColumn as PretableCoreColumn,`. The line becomes: + +```ts +// Re-exports from @pretable/core +export type { + PretableColumn as PretableCoreColumn, + PretableGrid, + PretableGridOptions, + PretableGridSnapshot, + PretableRow, +} from "@pretable/core"; +``` + +This keeps react's public surface stable (`PretableCoreColumn` still importable from `@pretable/react`); PR 3's audit will replace this alias with whatever shape react settles on. + +- [ ] **Step 3: Verify typecheck across react and consumers** + +```bash +pnpm --filter @pretable/react typecheck && \ +pnpm --filter @pretable/app-website typecheck && \ +pnpm --filter @pretable/app-bench typecheck +``` + +Expected: all pass. + +- [ ] **Step 4: Commit** + +```bash +git add packages/react/src/types.ts packages/react/src/index.ts +git commit -m "refactor(react): rename import aliases for renamed core types + +types.ts imports core's PretableColumn as PretableBaseColumn to +disambiguate from react's own PretableColumn. index.ts re-exports +PretableColumn as PretableCoreColumn so react's public surface is +unchanged — PR 3 will revisit the surface during the react audit. + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 5: Write `@pretable/core/src/public_api.ts` with TSDoc; collapse `index.ts` + +**Files:** +- Create: `packages/core/src/public_api.ts` +- Modify: `packages/core/src/index.ts` + +- [ ] **Step 1: Create `packages/core/src/public_api.ts`** + +Write the full curated public surface. Each symbol has TSDoc + `@public`. Use this content: + +```ts +/** + * Public API of `@pretable/core`. Hand-curated re-exports — do not edit + * `index.ts` directly. Internal symbols stay in their source files and + * are not re-exported here. + * + * @packageDocumentation + */ + +export { createGrid } from "./create-grid"; +export type { PretableGrid } from "./pretable-grid"; + +export type { + /** Tuning knobs for column autosize calculations. @public */ + AutosizeOptions, + /** Cell address — the (rowId, columnId) pair that uniquely identifies a cell. @public */ + PretableCellAddress, + /** Inclusive cell range — both bounds (start and end) are inside the selection. @public */ + PretableCellRange, + /** Engine-level column definition. `@pretable/react` extends this with React-specific render fields. @public */ + PretableColumn, + /** Direction passed to {@link PretableGrid.moveFocus}. @public */ + PretableFocusDirection, + /** Currently focused cell — both fields are null when nothing is focused. @public */ + PretableFocusState, + /** Input passed to a column's `format` function. @public */ + PretableFormatInput, + /** Options accepted by {@link createGrid}. @public */ + PretableGridOptions, + /** Read-only state observed via {@link PretableGrid.getSnapshot}. @public */ + PretableGridSnapshot, + /** Optional behavior modifiers for {@link PretableGrid.moveFocus}. @public */ + PretableMoveFocusOptions, + /** Base row constraint — every row is at minimum a string-keyed record. @public */ + PretableRow, + /** Per-row selection state — "selected" means fully, "indeterminate" means partial. @public */ + PretableRowSelectionTriState, + /** Cell-range selection state including the optional anchor for shift-extension. @public */ + PretableSelectionState, + /** Sort direction — `null` means unsorted. @public */ + PretableSortDirection, + /** Active sort. `columnId` is null when no column is sorted. @public */ + PretableSortState, + /** Streaming transaction — incremental row mutations applied via {@link PretableGrid.applyTransaction}. @public */ + PretableTransaction, + /** Viewport-level scroll + size state. @public */ + PretableViewportState, + /** A row currently in the visible window — includes its source-array index for stable identity. @public */ + PretableVisibleRow, +} from "./types"; + +export type { + /** Half-open row index range exposed via {@link PretableGridSnapshot.visibleRange}. @public */ + PretableRowRange, +} from "./types"; +``` + +Note: api-extractor reads the `@public` from TSDoc; the `/** ... */` block must directly precede the symbol. Inline-comment `@public` placement (as written here) works because each symbol is on its own line with the comment directly above. If api-extractor flags any as missing, hoist the TSDoc to a separate `/** ... @public */` block above the symbol. + +Wait — TSDoc release tags must be on a doc comment attached to a *declaration*, not on a re-export line. Re-exports cannot carry release tags this way. Instead, the release tags must live on the original declarations in `@pretable-internal/grid-core/src/types.ts` and `@pretable-internal/layout-core/src/types.ts`. This step is updated below. + +- [ ] **Step 2: Replace `public_api.ts` with the simpler re-export shell** + +Overwrite `packages/core/src/public_api.ts` with: + +```ts +/** + * Public API of `@pretable/core`. Hand-curated re-exports — do not edit + * `index.ts` directly. Internal symbols stay in their source files and + * are not re-exported here. + * + * @packageDocumentation + */ + +export { createGrid } from "./create-grid"; +export type { PretableGrid } from "./pretable-grid"; + +export type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableRowRange, + PretableRowSelectionTriState, + PretableSelectionState, + PretableSortDirection, + PretableSortState, + PretableTransaction, + PretableViewportState, + PretableVisibleRow, +} from "./types"; +``` + +- [ ] **Step 3: Add `@public` + TSDoc to `@pretable-internal/grid-core/src/types.ts`** + +This is where the tags actually attach. Apply this TSDoc above each exported symbol. Open `packages/grid-core/src/types.ts` and add the comment blocks: + +```ts +/** + * Tuning knobs for column autosize calculations. + * @public + */ +// (Above the existing `export type GridCoreSortDirection` block) +``` + +The full set of additions follows. For each interface/type below, prepend the indicated TSDoc comment immediately above the declaration: + +| Symbol | TSDoc summary | +|---|---| +| `PretableRow` | "Base row constraint — every row is at minimum a string-keyed record." | +| `PretableSortDirection` | "Sort direction — \`null\` means unsorted." | +| `PretableColumn` | "Engine-level column definition. \`@pretable/react\` extends this with React-specific render fields." | +| `PretableFormatInput` | "Input passed to a column's \`format\` function." | +| `PretableGridOptions` | "Options accepted by \`createGrid\`." | +| `PretableSortState` | "Active sort. \`columnId\` is null when no column is sorted." | +| `PretableCellAddress` | "Cell address — the (rowId, columnId) pair that uniquely identifies a cell." | +| `PretableCellRange` | "Inclusive cell range — both bounds (start and end) are inside the selection." | +| `PretableSelectionState` | "Cell-range selection state including the optional anchor for shift-extension." | +| `PretableFocusState` | "Currently focused cell — both fields are null when nothing is focused." | +| `PretableViewportState` | "Viewport-level scroll + size state." | +| `PretableTransaction` | "Streaming transaction — incremental row mutations applied via \`PretableGrid.applyTransaction\`." | +| `PretableVisibleRow` | "A row currently in the visible window — includes its source-array index for stable identity." | +| `PretableGridSnapshot` | "Read-only state observed via \`PretableGrid.getSnapshot\`." | +| `PretableEngine` | "@internal" (this is intentionally not public — keeps it out of the report) | +| `PretableFocusDirection` | "Direction passed to \`PretableGrid.moveFocus\`." | +| `PretableMoveFocusOptions` | "Optional behavior modifiers for \`PretableGrid.moveFocus\`." | +| `PretableFrame` | "@internal" (not public) | + +The format for each comment block: + +```ts +/** + * + * + * @public + */ +export interface PretableColumn { + ... +} +``` + +For the two `@internal` symbols (`PretableEngine`, `PretableFrame`), use: + +```ts +/** + * @internal + */ +export interface PretableEngine { + ... +} +``` + +- [ ] **Step 4: Add `@public` + TSDoc to `PretableRowSelectionTriState` in `derived-selection.ts`** + +In `packages/grid-core/src/derived-selection.ts`, find: +```ts +export type PretableRowSelectionTriState = "selected" | "indeterminate"; +``` + +Prepend: +```ts +/** + * Per-row selection state — "selected" means fully, "indeterminate" means partial. + * + * @public + */ +export type PretableRowSelectionTriState = "selected" | "indeterminate"; +``` + +The other two exports from this file (`deriveSelectedRows`, `rangeContainsCell`) are not in `@pretable/core`'s public surface but are exported from `@pretable-internal/grid-core` for cross-package use. Tag them `@internal`: + +```ts +/** + * @internal + */ +export function deriveSelectedRows(...) { ... } + +/** + * @internal + */ +export function rangeContainsCell(...) { ... } +``` + +- [ ] **Step 5: Add `@public` to `PretableRowRange` in `layout-core/src/types.ts`** + +It already received the TSDoc in Task 1 — verify by reading the file. If the `@public` tag is present in the comment block above `PretableRowRange`, no action. Otherwise add it. + +- [ ] **Step 6: Tag remaining `layout-core` exports as `@internal`** + +`@pretable-internal/layout-core` exports many symbols (`AutosizeColumnDef`, `ColumnPlan`, `PinnedColumnInput`, `PlanColumnsColumnInput`, `PlanColumnsInput`, `PlannedColumn`, `PlannedPinnedColumn`, `PlannedRow`, `PlanViewportInput`, `RowMetricsIndex`, `ViewportPlan`, `createRowMetricsIndex`, `planColumns`, `planViewport`, `autosizeColumns`, `AutosizeColumnsInput`, `AutosizeResult`). None are public. `AutosizeOptions` is public (re-exported from `@pretable/core`). + +Open `packages/layout-core/src/types.ts` and prepend `/** @public */` to `AutosizeOptions` and `/** @internal */` to every other exported symbol. + +In `packages/layout-core/src/index.ts` — only the re-exports happen; no declarations to tag. + +- [ ] **Step 7: Collapse `packages/core/src/index.ts`** + +Overwrite with one line: + +```ts +export * from "./public_api"; +``` + +- [ ] **Step 8: Verify typecheck** + +```bash +pnpm --filter @pretable/core typecheck && \ +pnpm --filter @pretable-internal/grid-core typecheck && \ +pnpm --filter @pretable-internal/layout-core typecheck +``` + +Expected: all pass. + +- [ ] **Step 9: Commit** + +```bash +git add packages/core/src packages/grid-core/src packages/layout-core/src +git commit -m "feat(core): hand-curated public_api.ts with @public TSDoc tags + +Adds @public TSDoc tags to every symbol exported through +@pretable/core's public surface, plus @internal tags on engine-only +symbols (PretableEngine, PretableFrame, deriveSelectedRows, +rangeContainsCell, layout-core's planning types). index.ts collapses to +a single re-export from public_api.ts. + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 6: Update `api-extractor.base.json` + +**Files:** +- Modify: `api-extractor.base.json` + +- [ ] **Step 1: Add internal packages to `bundledPackages`** + +Open `api-extractor.base.json`. Find the `bundledPackages` array and append the two internal packages so the report inlines their types: + +```json +"bundledPackages": [ + "@pretable/core", + "@pretable/react", + "@pretable/ui", + "@pretable/stream-adapter", + "@pretable-internal/grid-core", + "@pretable-internal/layout-core" +] +``` + +- [ ] **Step 2: Flip `ae-missing-release-tag` to `warning`** + +In the same file, the `extractorMessageReporting` block currently reads: + +```json +"ae-missing-release-tag": { + "logLevel": "none" +} +``` + +(or similar — PR 1's actual setting). Change to: + +```json +"ae-missing-release-tag": { + "logLevel": "warning" +} +``` + +This surfaces tag-coverage gaps in subsequent PRs without failing CI in non-local mode (warnings are non-fatal). + +- [ ] **Step 3: Build everything so api-extractor sees the new types** + +```bash +pnpm -r --filter '@pretable/core' --filter '@pretable/react' --filter '@pretable/stream-adapter' --filter '@pretable/ui' build +``` + +Expected: every package builds, including the underlying `@pretable-internal/*` builds chained from the `@pretable/*` build scripts. + +- [ ] **Step 4: Smoke-test api-extractor with the new config (just core)** + +```bash +pnpm --filter @pretable/core api +``` + +Expected: `API Extractor completed successfully`. The regenerated `core.api.md` should now show: +- Zero `ae-forgotten-export` warnings. +- Every public symbol annotated `// @public` (not `@public (undocumented)`). +- `PretableGrid` rendered as a flat interface (not `extends Omit<...>`). + +If any of those don't hold, debug before continuing. + +- [ ] **Step 5: Commit** + +```bash +git add api-extractor.base.json +git commit -m "chore(api): bundle internal packages; flip missing-release-tag to warning + +bundledPackages now inlines @pretable-internal/grid-core and +@pretable-internal/layout-core into each report so renamed types appear +self-contained. ae-missing-release-tag was 'none' for the PR 1 baseline; +flips to 'warning' now that core is fully tagged — provides coverage +visibility for PRs 3-5 without failing CI. + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 7: Regenerate `.api.md` files + +**Files:** +- Modify: `packages/core/core.api.md` +- Modify: `packages/react/react.api.md` + +- [ ] **Step 1: Regenerate all four reports** + +```bash +pnpm api +``` + +Expected: all four `API Extractor completed successfully`. May take 30-60 seconds (full build first). + +- [ ] **Step 2: Inspect `core.api.md` for shape** + +```bash +head -30 packages/core/core.api.md +``` + +Expected first lines: +``` +## API Report File for "@pretable/core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public +export interface AutosizeOptions { + ... +} +``` + +`AutosizeOptions`, `createGrid`, and every type should appear with `// @public` (not `@public (undocumented)`). Search for `(undocumented)` in the file: + +```bash +grep -n "(undocumented)" packages/core/core.api.md || echo "fully documented" +``` + +Expected: `fully documented` (every member-level fields may still show `(undocumented)` since we only TSDoc'd the top-level types — that's acceptable for this PR). + +Actually fields and members WILL still show `(undocumented)` because we only added TSDoc on the type/interface declarations, not on individual members. That's expected and acceptable; cleaning up member-level documentation is out of scope for this PR. + +- [ ] **Step 3: Verify `react.api.md` diff is rename-only** + +```bash +git diff packages/react/react.api.md | head -80 +``` + +Expected: line-level diff shows `GridCore*` → `Pretable*` renames; types like `PretableColumn` (extending core's renamed type) re-exported under same names. NO new symbols, NO removed symbols, NO shape changes (no added/removed fields, no method signature changes). + +If the diff includes shape changes (e.g., a method signature is different, a field appeared or disappeared), STOP — investigate. PR 2's spec says react's diff must be mechanical rename only. + +- [ ] **Step 4: Verify all four `api:check` pass** + +```bash +pnpm api:check +``` + +Expected: all four packages report `API Extractor completed successfully`, exit 0. + +- [ ] **Step 5: Commit** + +```bash +git add packages/core/core.api.md packages/react/react.api.md packages/ui/ui.api.md packages/stream-adapter/stream-adapter.api.md +git commit -m "chore(api): regenerate .api.md after engine type rename + +core.api.md: zero ae-forgotten-export warnings; every public symbol +annotated @public; PretableGrid is a flat interface. +react.api.md: mechanical rename diff only — no shape changes. +ui.api.md, stream-adapter.api.md: no expected change but regenerated for +consistency. + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 8: Write `packages/core/README.md` + +**Files:** +- Create: `packages/core/README.md` + +- [ ] **Step 1: Write the README** + +Create `packages/core/README.md` with this content: + +```markdown +# @pretable/core + +The headless engine for [pretable](https://pretable.dev/). Drives sort, filter, selection, focus, viewport, and streaming-transaction state for any table-shaped UI. + +## When to reach for this + +Most users want **[`@pretable/react`](../react)** instead. It bundles `@pretable/core` with a React surface that handles rendering, layout, and keyboard interaction. + +`@pretable/core` is for users building their own UI from scratch — for example, plain DOM, a non-React framework, or a custom canvas/webgl renderer. Headless usage is supported (the `createGrid` factory returns a fully-typed `PretableGrid` handle), but **dedicated docs, examples, and demos for headless mode are forthcoming**. If headless is what you're after, the type definitions and [`core.api.md`](./core.api.md) are the source of truth today. + +## Install + +```sh +npm install @pretable/core +# or pnpm add @pretable/core, yarn add @pretable/core +``` + +## Minimal example + +```ts +import { createGrid } from "@pretable/core"; + +const grid = createGrid({ + columns: [ + { id: "name", header: "Name" }, + { id: "age", header: "Age", sortable: true }, + ], + rows: [ + { id: "1", name: "Ada", age: 36 }, + { id: "2", name: "Grace", age: 85 }, + ], +}); + +grid.subscribe(() => { + const { visibleRows, sort } = grid.getSnapshot(); + console.log("rows:", visibleRows.length, "sort:", sort); +}); + +grid.setSort("age", "desc"); +``` + +## Full public surface + +See **[`core.api.md`](./core.api.md)** for every exported type, interface, and function with their full signatures. The file is generated by [API Extractor](https://api-extractor.com/) and committed to the repo; CI fails if it drifts. + +## License + +MIT — see [LICENSE](../../LICENSE). +``` + +- [ ] **Step 2: Commit** + +```bash +git add packages/core/README.md +git commit -m "docs(core): add per-package README + +Co-Authored-By: Claude Opus 4.7 " +``` + +--- + +## Task 9: Final repo-wide gates and PR + +**Files:** none (verification + push + PR creation) + +- [ ] **Step 1: Run all repo-wide gates** + +```bash +pnpm -w typecheck && pnpm -w test && pnpm -w lint && pnpm format && pnpm api:check +``` + +Expected: every command exits 0. + +- [ ] **Step 2: Sanity check the diff stays inside PR 2's scope** + +```bash +git diff main..HEAD --stat | tail -5 +``` + +Expect: file changes inside `packages/core`, `packages/grid-core`, `packages/layout-core`, `packages/renderer-dom`, `packages/react/src/{types.ts,index.ts}`, `api-extractor.base.json`, `packages/react/react.api.md`. No website changes. No bench changes. No engine-behavior code changes (only type renames). + +- [ ] **Step 3: Push** + +```bash +git push -u origin api-stabilization-core +``` + +- [ ] **Step 4: Open the PR** + +```bash +gh pr create --title "refactor(core): audit @pretable/core public surface; rename GridCore* → Pretable* at engine source" --body "$(cat <<'EOF' +## Summary + +PR 2 of 5 for [Tier 1 Sub-project A — Public API Stabilization](docs/superpowers/specs/2026-05-07-tier1-public-api-stabilization-design.md). Audits \`@pretable/core\`'s public surface per [PR 2's design spec](docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md). + +- Renames every \`GridCore*\` type at engine source to its natural \`Pretable*\` name. Internal-only \`GridCoreStore\` becomes \`PretableEngine\` (kept private); a brand-new explicit \`PretableGrid\` interface in \`@pretable/core\` replaces the old \`extends Omit, "options">\` leak. +- \`@pretable/core/types.ts\` collapses from ~50 lines of aliases to a clean re-export shell. +- \`@pretable/core/public_api.ts\` is the new hand-curated public surface; \`index.ts\` is one line. +- Every public symbol carries TSDoc + \`@public\`. \`@internal\` tags on engine-only symbols (PretableEngine, PretableFrame, deriveSelectedRows, rangeContainsCell, layout-core's planning types). +- \`api-extractor.base.json\` adds \`@pretable-internal/grid-core\` and \`@pretable-internal/layout-core\` to \`bundledPackages\` so the renamed types appear inlined in \`core.api.md\`. \`ae-missing-release-tag\` flips from \`none\` (PR 1 baseline) to \`warning\` (visible coverage signal for PRs 3-5). +- \`packages/core/README.md\` ships a prose intro mentioning headless usage as a forthcoming story. + +## react.api.md changes + +The rename ripples mechanically into \`@pretable/react\`'s import alias (\`PretableColumn as PretableBaseColumn\` in \`types.ts\`) and one re-export rename (\`PretableColumn as PretableCoreColumn\` in \`index.ts\`). \`react.api.md\` regenerates with **rename-only** diff — no shape change. PR 3's audit will fully resolve react's surface (likely retiring the \`PretableCoreColumn\` alias). + +## Headless docs deferral + +Per memory, full headless docs/examples/demos are deferred. README mentions headless support; \`core.api.md\` is the source of truth. + +## Test plan +- [x] \`pnpm -w typecheck\` clean +- [x] \`pnpm -w test\` clean +- [x] \`pnpm -w lint\` clean +- [x] \`pnpm format\` clean +- [x] \`pnpm api:check\` clean (all 4 packages) +- [x] \`core.api.md\` has zero \`ae-forgotten-export\` warnings +- [x] \`react.api.md\` diff is rename-only (no shape changes) + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +EOF +)" +``` + +- [ ] **Step 5: Set auto-merge** + +```bash +gh pr merge --auto --squash +``` + +--- + +## Self-review checklist + +- **Spec coverage:** every requirement in the spec maps to a task. Rename map (§Components) → Tasks 1-2. Explicit `PretableGrid` (§Architecture) → Task 3. Release tags (§TSDoc style) → Task 5. `bundledPackages` + tag flip (§ae-missing-release-tag config) → Task 6. README (§Per-package README) → Task 8. Success criteria all map: zero forgotten-export = Task 7 step 2; @public coverage = Task 5; explicit PretableGrid = Task 3; rename-only react diff = Task 7 step 3; README = Task 8; gates = Task 9. +- **Placeholder scan:** no \`TBD\`, \`TODO\`, "implement later", or "etc." in any task body. +- **Type/name consistency:** the rename map in Task 2 matches what Tasks 3, 4, 5, and 7 reference. `PretableEngine` is consistently used for the internal handle; `PretableGrid` is consistently used for the public interface. `PretableRowRange` (Task 1) is referenced in Tasks 5 and 7. +- **Important note on Task 5 Step 1:** the first attempt at the file (with TSDoc tags inline on re-export lines) is included as a documented failure mode. Step 2 corrects it. Implementers can skip Step 1 and go straight to Step 2 if they understand TSDoc release tags must attach to declarations, not re-exports — but the inline failure is documented so the implementer doesn't have to rediscover it. From 0f3b2ac2d5dab6b9860f91994d4c14a0e066dcc2 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:46:05 -0700 Subject: [PATCH 03/11] =?UTF-8?q?refactor(layout-core):=20rename=20LayoutS?= =?UTF-8?q?pan=20=E2=86=92=20PretableRowRange?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- packages/grid-core/src/types.ts | 4 ++-- packages/layout-core/src/index.ts | 2 +- packages/layout-core/src/types.ts | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/grid-core/src/types.ts b/packages/grid-core/src/types.ts index 8156a0d3f..22380fb31 100644 --- a/packages/grid-core/src/types.ts +++ b/packages/grid-core/src/types.ts @@ -1,6 +1,6 @@ import type { AutosizeOptions, - LayoutSpan, + PretableRowRange, } from "@pretable-internal/layout-core"; export type GridCoreRow = Record; @@ -90,7 +90,7 @@ export interface GridCoreSnapshot { focus: GridCoreFocusState; totalRowCount: number; visibleRows: GridCoreRowModel[]; - visibleRange: LayoutSpan; + visibleRange: PretableRowRange; } export interface GridCoreStore { diff --git a/packages/layout-core/src/index.ts b/packages/layout-core/src/index.ts index 215bf10cb..be164a2b9 100644 --- a/packages/layout-core/src/index.ts +++ b/packages/layout-core/src/index.ts @@ -8,7 +8,7 @@ export type { AutosizeOptions, AutosizeResult, ColumnPlan, - LayoutSpan, + PretableRowRange, PinnedColumnInput, PlanColumnsColumnInput, PlanColumnsInput, diff --git a/packages/layout-core/src/types.ts b/packages/layout-core/src/types.ts index 9a16cbf58..c8f038e8e 100644 --- a/packages/layout-core/src/types.ts +++ b/packages/layout-core/src/types.ts @@ -1,4 +1,10 @@ -export interface LayoutSpan { +/** + * Half-open row index range — `start` inclusive, `end` exclusive — used to + * describe the visible row window in {@link PretableGridSnapshot.visibleRange}. + * + * @public + */ +export interface PretableRowRange { start: number; end: number; } @@ -39,7 +45,7 @@ export interface PlanViewportInput { } export interface ViewportPlan { - range: LayoutSpan; + range: PretableRowRange; rows: PlannedRow[]; totalHeight: number; pinned: { From c093e348bc1f914d98b75276f181371cc95ae7a4 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:46:41 -0700 Subject: [PATCH 04/11] =?UTF-8?q?refactor(grid-core):=20rename=20GridCore*?= =?UTF-8?q?=20=E2=86=92=20Pretable*=20at=20source?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Engine-level types now use Pretable* names directly. Internal-only GridCoreStore renamed to PretableEngine to distinguish from the public PretableGrid interface (defined separately in @pretable/core). Co-Authored-By: Claude Opus 4.7 --- .../src/__tests__/selection-state.test.ts | 8 +- packages/grid-core/src/create-grid-core.ts | 120 +++++++++--------- packages/grid-core/src/derived-rows.ts | 44 +++---- packages/grid-core/src/derived-selection.ts | 26 ++-- packages/grid-core/src/index.ts | 38 +++--- packages/grid-core/src/types.ts | 84 ++++++------ packages/renderer-dom/src/create-renderer.ts | 20 +-- packages/renderer-dom/src/types.ts | 20 +-- 8 files changed, 180 insertions(+), 180 deletions(-) diff --git a/packages/grid-core/src/__tests__/selection-state.test.ts b/packages/grid-core/src/__tests__/selection-state.test.ts index 389d0519c..7372f9df5 100644 --- a/packages/grid-core/src/__tests__/selection-state.test.ts +++ b/packages/grid-core/src/__tests__/selection-state.test.ts @@ -3,7 +3,7 @@ import { describe, expect, test } from "vitest"; import { createGridCore, deriveSelectedRows, - type GridCoreCellRange, + type PretableCellRange, } from "../index"; interface DemoRow { @@ -44,7 +44,7 @@ describe("selection state", () => { test("setSelection replaces ranges and anchor", () => { const grid = makeGrid(); - const range: GridCoreCellRange = { + const range: PretableCellRange = { startRowId: "a", endRowId: "b", startColumnId: "name", @@ -103,13 +103,13 @@ describe("selection state", () => { test("addRange appends and updates anchor to range start", () => { const grid = makeGrid(); - const r1: GridCoreCellRange = { + const r1: PretableCellRange = { startRowId: "a", endRowId: "a", startColumnId: "name", endColumnId: "name", }; - const r2: GridCoreCellRange = { + const r2: PretableCellRange = { startRowId: "c", endRowId: "c", startColumnId: "message", diff --git a/packages/grid-core/src/create-grid-core.ts b/packages/grid-core/src/create-grid-core.ts index a95797e30..b37365dfa 100644 --- a/packages/grid-core/src/create-grid-core.ts +++ b/packages/grid-core/src/create-grid-core.ts @@ -6,39 +6,39 @@ import { type SourceRow, } from "./derived-rows"; import type { - GridCoreCellAddress, - GridCoreCellRange, - GridCoreColumn, - GridCoreFocusDirection, - GridCoreFocusState, - GridCoreMoveFocusOptions, - GridCoreOptions, - GridCoreRow, - GridCoreRowModel, - GridCoreSelectionState, - GridCoreSnapshot, - GridCoreSortDirection, - GridCoreSortState, - GridCoreStore, - GridCoreTransaction, - GridCoreViewportState, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableMoveFocusOptions, + PretableGridOptions, + PretableRow, + PretableVisibleRow, + PretableSelectionState, + PretableGridSnapshot, + PretableSortDirection, + PretableSortState, + PretableEngine, + PretableTransaction, + PretableViewportState, } from "./types"; const ROW_SELECT_COLUMN_ID = "__pretable_row_select__"; -function clampColumnWidth( +function clampColumnWidth( width: number, - column: GridCoreColumn, + column: PretableColumn, ): number { const min = column.minWidthPx ?? 40; const max = column.maxWidthPx ?? Infinity; return Math.max(min, Math.min(max, width)); } -function applyAutosize( - options: GridCoreOptions, +function applyAutosize( + options: PretableGridOptions, autosizeOptions?: AutosizeOptions, -): GridCoreOptions { +): PretableGridOptions { const result = autosizeColumns({ columns: options.columns, rows: options.rows, @@ -62,9 +62,9 @@ function applyAutosize( return { ...options, columns: nextColumns }; } -export function createGridCore( - inputOptions: GridCoreOptions, -): GridCoreStore { +export function createGridCore( + inputOptions: PretableGridOptions, +): PretableEngine { const listeners = new Set<() => void>(); let options = inputOptions.autosize ? applyAutosize( @@ -74,22 +74,22 @@ export function createGridCore( : undefined, ) : inputOptions; - let originalColumns: GridCoreColumn[] = inputOptions.columns.map( + let originalColumns: PretableColumn[] = inputOptions.columns.map( (c) => ({ ...c }), ); let sourceRows = createSourceRows(options); const sourceRowIndex = new Map>( sourceRows.map((entry) => [entry.id, entry]), ); - let cachedSnapshot: GridCoreSnapshot | null = null; - let cachedVisibleRows: GridCoreRowModel[] | null = null; - let cachedDerivedSort: GridCoreSortState | null = null; + let cachedSnapshot: PretableGridSnapshot | null = null; + let cachedVisibleRows: PretableVisibleRow[] | null = null; + let cachedDerivedSort: PretableSortState | null = null; let cachedDerivedFilters: Record | null = null; - let sort: GridCoreSortState = { columnId: null, direction: null }; + let sort: PretableSortState = { columnId: null, direction: null }; let filters: Record = {}; - let selection: GridCoreSelectionState = { ranges: [], anchor: null }; - let focus: GridCoreFocusState = { rowId: null, columnId: null }; - let viewport: GridCoreViewportState = { + let selection: PretableSelectionState = { ranges: [], anchor: null }; + let focus: PretableFocusState = { rowId: null, columnId: null }; + let viewport: PretableViewportState = { scrollTop: 0, scrollLeft: 0, height: 0, @@ -108,7 +108,7 @@ export function createGridCore( }; }, getSnapshot, - setSort(columnId: string | null, direction: GridCoreSortDirection) { + setSort(columnId: string | null, direction: PretableSortDirection) { if (sort.columnId === columnId && sort.direction === direction) { return; } @@ -165,7 +165,7 @@ export function createGridCore( filters = normalized; emit(); }, - setSelection(next: GridCoreSelectionState) { + setSelection(next: PretableSelectionState) { if (selectionsEqual(selection, next)) { return; } @@ -187,18 +187,18 @@ export function createGridCore( return; } - const range: GridCoreCellRange = { + const range: PretableCellRange = { startRowId: firstRow.id, endRowId: lastRow.id, startColumnId: firstColumn.id, endColumnId: lastColumn.id, }; - const anchor: GridCoreCellAddress = { + const anchor: PretableCellAddress = { rowId: firstRow.id, columnId: firstColumn.id, }; - const next: GridCoreSelectionState = { ranges: [range], anchor }; + const next: PretableSelectionState = { ranges: [range], anchor }; if (selectionsEqual(selection, next)) { return; @@ -212,7 +212,7 @@ export function createGridCore( focus.rowId && focus.columnId ? { rowId: focus.rowId, columnId: focus.columnId } : null; - const next: GridCoreSelectionState = focusAddr + const next: PretableSelectionState = focusAddr ? { ranges: [ { @@ -233,19 +233,19 @@ export function createGridCore( selection = next; emit(); }, - addRange(range: GridCoreCellRange) { + addRange(range: PretableCellRange) { selection = { ranges: [...selection.ranges, { ...range }], anchor: { rowId: range.startRowId, columnId: range.startColumnId }, }; emit(); }, - extendRangeFromAnchor(addr: GridCoreCellAddress) { + extendRangeFromAnchor(addr: PretableCellAddress) { if (!selection.anchor) { return; } - const newActive: GridCoreCellRange = { + const newActive: PretableCellRange = { startRowId: selection.anchor.rowId, endRowId: addr.rowId, startColumnId: selection.anchor.columnId, @@ -268,7 +268,7 @@ export function createGridCore( return; } - const fullRowRange: GridCoreCellRange = { + const fullRowRange: PretableCellRange = { startRowId: rowId, endRowId: rowId, startColumnId: firstColumn.id, @@ -307,10 +307,10 @@ export function createGridCore( !visibleIds.has(r.startRowId), ); - let next: GridCoreSelectionState; + let next: PretableSelectionState; if (checked) { - const newRanges = snapshot.visibleRows.map( + const newRanges = snapshot.visibleRows.map( (row) => ({ startRowId: row.id, endRowId: row.id, @@ -336,7 +336,7 @@ export function createGridCore( selection = next; emit(); }, - setFocus(addr: GridCoreCellAddress | null) { + setFocus(addr: PretableCellAddress | null) { const nextRowId = addr?.rowId ?? null; const nextColumnId = addr?.columnId ?? null; @@ -348,8 +348,8 @@ export function createGridCore( emit(); }, moveFocus( - direction: GridCoreFocusDirection, - moveOptions: GridCoreMoveFocusOptions = {}, + direction: PretableFocusDirection, + moveOptions: PretableMoveFocusOptions = {}, ) { const snapshot = getSnapshot(); const visibleRows = snapshot.visibleRows; @@ -447,7 +447,7 @@ export function createGridCore( return; } - const nextAddr: GridCoreCellAddress = { + const nextAddr: PretableCellAddress = { rowId: nextRow.id, columnId: nextColumn.id, }; @@ -468,7 +468,7 @@ export function createGridCore( anchor: nextAddr, }; } else { - const newActive: GridCoreCellRange = { + const newActive: PretableCellRange = { startRowId: selection.anchor.rowId, endRowId: nextAddr.rowId, startColumnId: selection.anchor.columnId, @@ -496,7 +496,7 @@ export function createGridCore( emit(); }, - setViewport(nextViewport: GridCoreViewportState) { + setViewport(nextViewport: PretableViewportState) { if ( viewport.scrollTop === nextViewport.scrollTop && viewport.scrollLeft === nextViewport.scrollLeft && @@ -618,7 +618,7 @@ export function createGridCore( } const insertAt = boundary; - const nextColumn: GridCoreColumn = { + const nextColumn: PretableColumn = { ...column, pinned: nextPinnedValue, }; @@ -690,7 +690,7 @@ export function createGridCore( options = { ...options, columns: next }; emit(); }, - mergeColumnsFromProps(nextColumns: GridCoreColumn[]) { + mergeColumnsFromProps(nextColumns: PretableColumn[]) { const currentById = new Map(options.columns.map((c) => [c.id, c])); const merged = nextColumns.map((newCol) => { const existing = currentById.get(newCol.id); @@ -707,10 +707,10 @@ export function createGridCore( options = { ...options, columns: merged }; emit(); }, - applyTransaction(transaction: GridCoreTransaction) { + applyTransaction(transaction: PretableTransaction) { if (!options.getRowId) { throw new Error( - "applyTransaction requires getRowId on GridCoreOptions", + "applyTransaction requires getRowId on PretableGridOptions", ); } @@ -775,7 +775,7 @@ export function createGridCore( return store; - function getSnapshot(): GridCoreSnapshot { + function getSnapshot(): PretableGridSnapshot { if (cachedSnapshot) { return cachedSnapshot; } @@ -829,9 +829,9 @@ function clamp(value: number, min: number, max: number): number { return Math.max(min, Math.min(max, value)); } -function computePageStep( +function computePageStep( viewport: { height: number }, - visibleRows: GridCoreRowModel[], + visibleRows: PretableVisibleRow[], ): number { if (viewport.height <= 0 || visibleRows.length === 0) { return 1; @@ -848,7 +848,7 @@ function computePageStep( } function isFullRowRange( - range: GridCoreCellRange, + range: PretableCellRange, rowId: string, firstColumnId: string, lastColumnId: string, @@ -862,8 +862,8 @@ function isFullRowRange( } function selectionsEqual( - a: GridCoreSelectionState, - b: GridCoreSelectionState, + a: PretableSelectionState, + b: PretableSelectionState, ): boolean { if (a.ranges.length !== b.ranges.length) { return false; diff --git a/packages/grid-core/src/derived-rows.ts b/packages/grid-core/src/derived-rows.ts index 90def43ee..44b739566 100644 --- a/packages/grid-core/src/derived-rows.ts +++ b/packages/grid-core/src/derived-rows.ts @@ -1,19 +1,19 @@ import type { - GridCoreColumn, - GridCoreOptions, - GridCoreRow, - GridCoreRowModel, - GridCoreSortState, + PretableColumn, + PretableGridOptions, + PretableRow, + PretableVisibleRow, + PretableSortState, } from "./types"; -export interface SourceRow { +export interface SourceRow { id: string; row: TRow; sourceIndex: number; } -export function createSourceRows( - options: GridCoreOptions, +export function createSourceRows( + options: PretableGridOptions, ): SourceRow[] { return options.rows.map((row, index) => ({ id: options.getRowId?.(row, index) ?? String(index), @@ -22,12 +22,12 @@ export function createSourceRows( })); } -export function deriveVisibleRows(input: { - columns: GridCoreColumn[]; +export function deriveVisibleRows(input: { + columns: PretableColumn[]; filters: Record; rows: SourceRow[]; - sort: GridCoreSortState; -}): GridCoreRowModel[] { + sort: PretableSortState; +}): PretableVisibleRow[] { const resolvedFilters = resolveFilters(input.columns, input.filters); const filtered = input.rows.filter((entry) => matchesFilters(entry.row, resolvedFilters), @@ -41,13 +41,13 @@ export function deriveVisibleRows(input: { })); } -interface ResolvedFilter { - column: GridCoreColumn; +interface ResolvedFilter { + column: PretableColumn; needle: string; } -function resolveFilters( - columns: GridCoreColumn[], +function resolveFilters( + columns: PretableColumn[], filters: Record, ): ResolvedFilter[] { const columnMap = new Map(columns.map((c) => [c.id, c])); @@ -70,7 +70,7 @@ function resolveFilters( return resolved; } -function matchesFilters( +function matchesFilters( row: TRow, resolvedFilters: ResolvedFilter[], ): boolean { @@ -90,10 +90,10 @@ const collator = new Intl.Collator(undefined, { sensitivity: "base", }); -function sortRows( +function sortRows( rows: SourceRow[], - columns: GridCoreColumn[], - sort: GridCoreSortState, + columns: PretableColumn[], + sort: PretableSortState, ): SourceRow[] { if (!sort.columnId || !sort.direction) { return [...rows]; @@ -136,9 +136,9 @@ function sortRows( return indexed.map((i) => rows[i]); } -function readCellValue( +function readCellValue( row: TRow, - column: GridCoreColumn, + column: PretableColumn, ): unknown { return column.value ? column.value(row) : row[column.id]; } diff --git a/packages/grid-core/src/derived-selection.ts b/packages/grid-core/src/derived-selection.ts index 5439ed70a..fcaef45cf 100644 --- a/packages/grid-core/src/derived-selection.ts +++ b/packages/grid-core/src/derived-selection.ts @@ -1,15 +1,15 @@ import type { - GridCoreCellRange, - GridCoreColumn, - GridCoreRow, - GridCoreRowModel, - GridCoreSelectionState, + PretableCellRange, + PretableColumn, + PretableRow, + PretableVisibleRow, + PretableSelectionState, } from "./types"; -export type RowSelectionTriState = "selected" | "indeterminate"; +export type PretableRowSelectionTriState = "selected" | "indeterminate"; export function rangeContainsCell( - range: GridCoreCellRange, + range: PretableCellRange, rowId: string, columnId: string, rowOrder: ReadonlyMap, @@ -47,13 +47,13 @@ export function rangeContainsCell( ); } -export function deriveSelectedRows(args: { - visibleRows: GridCoreRowModel[]; - columns: GridCoreColumn[]; - selection: GridCoreSelectionState; -}): Map { +export function deriveSelectedRows(args: { + visibleRows: PretableVisibleRow[]; + columns: PretableColumn[]; + selection: PretableSelectionState; +}): Map { const { visibleRows, columns, selection } = args; - const result = new Map(); + const result = new Map(); if (selection.ranges.length === 0 || columns.length === 0) { return result; diff --git a/packages/grid-core/src/index.ts b/packages/grid-core/src/index.ts index f3720224e..2452476d1 100644 --- a/packages/grid-core/src/index.ts +++ b/packages/grid-core/src/index.ts @@ -2,26 +2,26 @@ export { createGridCore } from "./create-grid-core"; export { deriveSelectedRows, rangeContainsCell, - type RowSelectionTriState, + type PretableRowSelectionTriState, } from "./derived-selection"; export type { - GridCoreCellAddress, - GridCoreCellRange, - GridCoreColumn, - GridCoreFocusDirection, - GridCoreFocusState, - GridCoreFormatInput, - GridCoreFrame, - GridCoreMoveFocusOptions, - GridCoreOptions, - GridCoreRow, - GridCoreRowModel, - GridCoreSelectionState, - GridCoreSnapshot, - GridCoreSortDirection, - GridCoreSortState, - GridCoreStore, - GridCoreTransaction, - GridCoreViewportState, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableFrame, + PretableMoveFocusOptions, + PretableGridOptions, + PretableRow, + PretableVisibleRow, + PretableSelectionState, + PretableGridSnapshot, + PretableSortDirection, + PretableSortState, + PretableEngine, + PretableTransaction, + PretableViewportState, } from "./types"; export type { AutosizeOptions } from "@pretable-internal/layout-core"; diff --git a/packages/grid-core/src/types.ts b/packages/grid-core/src/types.ts index 22380fb31..ab8e0a0b3 100644 --- a/packages/grid-core/src/types.ts +++ b/packages/grid-core/src/types.ts @@ -3,10 +3,10 @@ import type { PretableRowRange, } from "@pretable-internal/layout-core"; -export type GridCoreRow = Record; -export type GridCoreSortDirection = "asc" | "desc" | null; +export type PretableRow = Record; +export type PretableSortDirection = "asc" | "desc" | null; -export interface GridCoreColumn { +export interface PretableColumn { id: string; header?: string; wrap?: boolean; @@ -15,7 +15,7 @@ export interface GridCoreColumn { sortable?: boolean; filterable?: boolean; value?: (row: TRow) => unknown; - format?: (input: GridCoreFormatInput) => string; + format?: (input: PretableFormatInput) => string; // new in sub-project C: minWidthPx?: number; maxWidthPx?: number; @@ -23,102 +23,102 @@ export interface GridCoreColumn { reorderable?: boolean; } -export interface GridCoreFormatInput { +export interface PretableFormatInput { value: unknown; row: TRow; - column: GridCoreColumn; + column: PretableColumn; } -export interface GridCoreOptions { - columns: GridCoreColumn[]; +export interface PretableGridOptions { + columns: PretableColumn[]; rows: TRow[]; getRowId?: (row: TRow, index: number) => string; autosize?: boolean | AutosizeOptions; } -export interface GridCoreSortState { +export interface PretableSortState { columnId: string | null; - direction: GridCoreSortDirection; + direction: PretableSortDirection; } -export interface GridCoreCellAddress { +export interface PretableCellAddress { rowId: string; columnId: string; } -export interface GridCoreCellRange { +export interface PretableCellRange { startRowId: string; endRowId: string; startColumnId: string; endColumnId: string; } -export interface GridCoreSelectionState { - ranges: GridCoreCellRange[]; - anchor: GridCoreCellAddress | null; +export interface PretableSelectionState { + ranges: PretableCellRange[]; + anchor: PretableCellAddress | null; } -export interface GridCoreFocusState { +export interface PretableFocusState { rowId: string | null; columnId: string | null; } -export interface GridCoreViewportState { +export interface PretableViewportState { scrollTop: number; scrollLeft: number; height: number; width: number; } -export interface GridCoreTransaction { +export interface PretableTransaction { add?: TRow[]; update?: Partial[]; remove?: string[]; } -export interface GridCoreRowModel { +export interface PretableVisibleRow { id: string; row: TRow; sourceIndex: number; } -export interface GridCoreSnapshot { - viewport: GridCoreViewportState; - sort: GridCoreSortState; +export interface PretableGridSnapshot { + viewport: PretableViewportState; + sort: PretableSortState; filters: Record; - selection: GridCoreSelectionState; - focus: GridCoreFocusState; + selection: PretableSelectionState; + focus: PretableFocusState; totalRowCount: number; - visibleRows: GridCoreRowModel[]; + visibleRows: PretableVisibleRow[]; visibleRange: PretableRowRange; } -export interface GridCoreStore { - options: GridCoreOptions; +export interface PretableEngine { + options: PretableGridOptions; subscribe(listener: () => void): () => void; - getSnapshot(): GridCoreSnapshot; - setSort(columnId: string | null, direction: GridCoreSortDirection): void; + getSnapshot(): PretableGridSnapshot; + setSort(columnId: string | null, direction: PretableSortDirection): void; setFilter(columnId: string, value: string): void; clearFilters(): void; replaceFilters(nextFilters: Record): void; // selection actions - setSelection(state: GridCoreSelectionState): void; + setSelection(state: PretableSelectionState): void; selectAll(): void; clearSelection(): void; - addRange(range: GridCoreCellRange): void; - extendRangeFromAnchor(addr: GridCoreCellAddress): void; + addRange(range: PretableCellRange): void; + extendRangeFromAnchor(addr: PretableCellAddress): void; toggleRowSelection(rowId: string): void; setSelectAllVisible(checked: boolean): void; // focus actions - setFocus(addr: GridCoreCellAddress | null): void; + setFocus(addr: PretableCellAddress | null): void; moveFocus( - direction: GridCoreFocusDirection, - options?: GridCoreMoveFocusOptions, + direction: PretableFocusDirection, + options?: PretableMoveFocusOptions, ): void; - setViewport(viewport: GridCoreViewportState): void; + setViewport(viewport: PretableViewportState): void; autosizeColumns(autosizeOptions?: AutosizeOptions): void; - applyTransaction(transaction: GridCoreTransaction): void; + applyTransaction(transaction: PretableTransaction): void; // column-layout actions (sub-project C): setColumnWidth(columnId: string, width: number): void; @@ -126,17 +126,17 @@ export interface GridCoreStore { setColumnPinned(columnId: string, pinned: "left" | null): void; autosizeColumn(columnId: string, options?: AutosizeOptions): void; resetColumnLayout(): void; - mergeColumnsFromProps(nextColumns: GridCoreColumn[]): void; + mergeColumnsFromProps(nextColumns: PretableColumn[]): void; } -export type GridCoreFocusDirection = "up" | "down" | "left" | "right"; +export type PretableFocusDirection = "up" | "down" | "left" | "right"; -export interface GridCoreMoveFocusOptions { +export interface PretableMoveFocusOptions { extend?: boolean; jumpToEdge?: boolean; byPage?: boolean; } -export interface GridCoreFrame { - snapshot: GridCoreSnapshot; +export interface PretableFrame { + snapshot: PretableGridSnapshot; } diff --git a/packages/renderer-dom/src/create-renderer.ts b/packages/renderer-dom/src/create-renderer.ts index 470b631bb..02b29f0c3 100644 --- a/packages/renderer-dom/src/create-renderer.ts +++ b/packages/renderer-dom/src/create-renderer.ts @@ -3,7 +3,7 @@ import { planColumns, planViewport, } from "@pretable-internal/layout-core"; -import type { GridCoreColumn, GridCoreRow } from "@pretable-internal/grid-core"; +import type { PretableColumn, PretableRow } from "@pretable-internal/grid-core"; import { layoutPreparedText, prepareText } from "@pretable-internal/text-core"; import type { DomRenderInput, DomRenderSnapshot } from "./types"; @@ -29,7 +29,7 @@ const estimatedRowHeightCache = new WeakMap< } >(); -export function createDomRenderSnapshot( +export function createDomRenderSnapshot( input: DomRenderInput, ): DomRenderSnapshot { const rowHeights = input.snapshot.visibleRows.map((entry) => { @@ -115,9 +115,9 @@ export function createDomRenderSnapshot( }; } -function estimateRowHeight( +function estimateRowHeight( row: TRow, - columns: GridCoreColumn[], + columns: PretableColumn[], ): number { const cached = estimatedRowHeightCache.get(row); @@ -164,9 +164,9 @@ function estimateRowHeight( return estimatedHeight; } -function getEstimatedRowHeightSignature( +function getEstimatedRowHeightSignature( row: TRow, - columns: GridCoreColumn[], + columns: PretableColumn[], ) { return columns .filter((column) => column.wrap) @@ -178,15 +178,15 @@ function getEstimatedRowHeightSignature( .join("|"); } -function readCellValue( +function readCellValue( row: TRow, - column: GridCoreColumn, + column: PretableColumn, ): unknown { return column.value ? column.value(row) : row[column.id]; } -function getColumnWidth( - column: GridCoreColumn, +function getColumnWidth( + column: PretableColumn, ): number { return ( column.widthPx ?? (column.wrap ? WRAPPED_COLUMN_WIDTH : FIXED_COLUMN_WIDTH) diff --git a/packages/renderer-dom/src/types.ts b/packages/renderer-dom/src/types.ts index 56df276d9..5911d94e3 100644 --- a/packages/renderer-dom/src/types.ts +++ b/packages/renderer-dom/src/types.ts @@ -1,14 +1,14 @@ import type { - GridCoreColumn, - GridCoreFrame, - GridCoreRow, - GridCoreSnapshot, + PretableColumn, + PretableFrame, + PretableRow, + PretableGridSnapshot, } from "@pretable-internal/grid-core"; import type { PlannedColumn } from "@pretable-internal/layout-core"; -export interface DomRenderInput { - columns: GridCoreColumn[]; - snapshot: GridCoreSnapshot; +export interface DomRenderInput { + columns: PretableColumn[]; + snapshot: PretableGridSnapshot; scrollTop: number; scrollLeft?: number; viewportHeight: number; @@ -17,7 +17,7 @@ export interface DomRenderInput { measuredHeights?: Record; } -export interface DomRenderRow { +export interface DomRenderRow { id: string; row: TRow; rowIndex: number; @@ -25,8 +25,8 @@ export interface DomRenderRow { height: number; } -export interface DomRenderSnapshot { - frame: GridCoreFrame; +export interface DomRenderSnapshot { + frame: PretableFrame; rows: DomRenderRow[]; columns: PlannedColumn[]; nodeCount: number; From d17d6c9e8a27fb09fcaaf6b1321ec3ec58ffc0d2 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:49:46 -0700 Subject: [PATCH 05/11] refactor(core): explicit PretableGrid interface; collapse types.ts Replaces extends Omit, 'options'> with an explicit interface listing every method/property pretable promises. types.ts becomes a re-export shell from the renamed engine types. Also re-exports PretableRowRange via grid-core (which already bridges layout-core), and updates core/index.ts to export PretableGrid from pretable-grid.ts. Co-Authored-By: Claude Opus 4.7 --- packages/core/src/create-grid.ts | 73 ++++++++++++++++++------------ packages/core/src/index.ts | 7 +-- packages/core/src/pretable-grid.ts | 73 ++++++++++++++++++++++++++++++ packages/core/src/types.ts | 63 ++++++++------------------ packages/grid-core/src/index.ts | 2 +- 5 files changed, 141 insertions(+), 77 deletions(-) create mode 100644 packages/core/src/pretable-grid.ts diff --git a/packages/core/src/create-grid.ts b/packages/core/src/create-grid.ts index 0b4c4552f..0b90c68b5 100644 --- a/packages/core/src/create-grid.ts +++ b/packages/core/src/create-grid.ts @@ -1,40 +1,57 @@ import { createGridCore } from "@pretable-internal/grid-core"; -import type { PretableGrid, PretableGridOptions } from "./types"; +import type { PretableGrid } from "./pretable-grid"; +import type { PretableGridOptions, PretableRow } from "./types"; -export function createGrid>( +/** + * Create a pretable grid instance. Returns a {@link PretableGrid} handle + * that exposes every action and observation pretable supports. + * + * @example + * ```ts + * const grid = createGrid({ + * columns: [{ id: "name" }, { id: "age" }], + * rows: [{ id: "1", name: "Ada", age: 36 }], + * }); + * grid.setSort("age", "desc"); + * const snapshot = grid.getSnapshot(); + * ``` + * + * @public + */ +export function createGrid( options: PretableGridOptions, ): PretableGrid { - const gridCore = createGridCore(options); + const engine = createGridCore(options); return { kind: "pretable-grid", get options() { - return gridCore.options; + return engine.options; }, - subscribe: gridCore.subscribe, - getSnapshot: gridCore.getSnapshot, - setSort: gridCore.setSort, - setFilter: gridCore.setFilter, - clearFilters: gridCore.clearFilters, - replaceFilters: gridCore.replaceFilters, - setSelection: gridCore.setSelection, - selectAll: gridCore.selectAll, - clearSelection: gridCore.clearSelection, - addRange: gridCore.addRange, - extendRangeFromAnchor: gridCore.extendRangeFromAnchor, - toggleRowSelection: gridCore.toggleRowSelection, - setSelectAllVisible: gridCore.setSelectAllVisible, - setFocus: gridCore.setFocus, - moveFocus: gridCore.moveFocus, - setViewport: gridCore.setViewport, - autosizeColumns: gridCore.autosizeColumns, - setColumnWidth: gridCore.setColumnWidth, - moveColumn: gridCore.moveColumn, - setColumnPinned: gridCore.setColumnPinned, - autosizeColumn: gridCore.autosizeColumn, - resetColumnLayout: gridCore.resetColumnLayout, - mergeColumnsFromProps: gridCore.mergeColumnsFromProps, - applyTransaction: gridCore.applyTransaction, + subscribe: engine.subscribe, + getSnapshot: engine.getSnapshot, + setSort: engine.setSort, + setFilter: engine.setFilter, + clearFilters: engine.clearFilters, + replaceFilters: engine.replaceFilters, + setSelection: engine.setSelection, + selectAll: engine.selectAll, + clearSelection: engine.clearSelection, + addRange: engine.addRange, + extendRangeFromAnchor: engine.extendRangeFromAnchor, + toggleRowSelection: engine.toggleRowSelection, + setSelectAllVisible: engine.setSelectAllVisible, + setFocus: engine.setFocus, + moveFocus: engine.moveFocus, + setViewport: engine.setViewport, + autosizeColumns: engine.autosizeColumns, + setColumnWidth: engine.setColumnWidth, + moveColumn: engine.moveColumn, + setColumnPinned: engine.setColumnPinned, + autosizeColumn: engine.autosizeColumn, + resetColumnLayout: engine.resetColumnLayout, + mergeColumnsFromProps: engine.mergeColumnsFromProps, + applyTransaction: engine.applyTransaction, }; } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a81cee79f..c7bfdd8f8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,14 +1,16 @@ export { createGrid } from "./create-grid"; +export type { PretableGrid } from "./pretable-grid"; export type { + AutosizeOptions, PretableCellAddress, PretableCellRange, - PretableCoreColumn, + PretableColumn, PretableFocusState, PretableFormatInput, - PretableGrid, PretableGridOptions, PretableGridSnapshot, PretableRow, + PretableRowRange, PretableSelectionState, PretableSortDirection, PretableSortState, @@ -16,4 +18,3 @@ export type { PretableViewportState, PretableVisibleRow, } from "./types"; -export type { AutosizeOptions } from "@pretable-internal/grid-core"; diff --git a/packages/core/src/pretable-grid.ts b/packages/core/src/pretable-grid.ts new file mode 100644 index 000000000..644ffe521 --- /dev/null +++ b/packages/core/src/pretable-grid.ts @@ -0,0 +1,73 @@ +import type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableSelectionState, + PretableSortDirection, + PretableTransaction, + PretableViewportState, +} from "@pretable-internal/grid-core"; + +/** + * Public handle returned by {@link createGrid}. Exposes every action and + * observation pretable promises to support; does not extend the internal + * engine type, so private methods cannot leak through the public surface. + * + * @public + */ +export interface PretableGrid { + /** Discriminator — distinguishes `PretableGrid` from arbitrary objects. */ + readonly kind: "pretable-grid"; + + /** The options the grid was constructed with. */ + readonly options: PretableGridOptions; + + /** Subscribe to grid mutations. Returns an unsubscribe function. */ + subscribe(listener: () => void): () => void; + + /** Read the current snapshot. Stable reference until the next mutation. */ + getSnapshot(): PretableGridSnapshot; + + // sort / filter + setSort(columnId: string | null, direction: PretableSortDirection): void; + setFilter(columnId: string, value: string): void; + clearFilters(): void; + replaceFilters(nextFilters: Record): void; + + // selection + setSelection(state: PretableSelectionState): void; + selectAll(): void; + clearSelection(): void; + addRange(range: PretableCellRange): void; + extendRangeFromAnchor(addr: PretableCellAddress): void; + toggleRowSelection(rowId: string): void; + setSelectAllVisible(checked: boolean): void; + + // focus + setFocus(addr: PretableCellAddress | null): void; + moveFocus( + direction: PretableFocusDirection, + options?: PretableMoveFocusOptions, + ): void; + + // viewport + setViewport(viewport: PretableViewportState): void; + + // column layout + autosizeColumns(options?: AutosizeOptions): void; + setColumnWidth(columnId: string, width: number): void; + moveColumn(columnId: string, toIndex: number): void; + setColumnPinned(columnId: string, pinned: "left" | null): void; + autosizeColumn(columnId: string, options?: AutosizeOptions): void; + resetColumnLayout(): void; + mergeColumnsFromProps(nextColumns: PretableColumn[]): void; + + // streaming + applyTransaction(transaction: PretableTransaction): void; +} diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 70ce24491..9d77184d4 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -1,48 +1,21 @@ -export type PretableRow = Record; export type { - GridCoreCellAddress as PretableCellAddress, - GridCoreCellRange as PretableCellRange, - GridCoreFocusDirection as PretableFocusDirection, - GridCoreFocusState as PretableFocusState, - GridCoreMoveFocusOptions as PretableMoveFocusOptions, - GridCoreRowModel as PretableVisibleRow, - GridCoreSelectionState as PretableSelectionState, - GridCoreSnapshot as PretableGridSnapshot, - GridCoreSortDirection as PretableSortDirection, - GridCoreSortState as PretableSortState, - GridCoreViewportState as PretableViewportState, - RowSelectionTriState as PretableRowSelectionTriState, -} from "@pretable-internal/grid-core"; -import type { AutosizeOptions, - GridCoreColumn, - GridCoreFormatInput, - GridCoreOptions, - GridCoreSnapshot, - GridCoreSortDirection, - GridCoreStore, - GridCoreTransaction, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableRowRange, + PretableRowSelectionTriState, + PretableSelectionState, + PretableSortDirection, + PretableSortState, + PretableTransaction, + PretableViewportState, + PretableVisibleRow, } from "@pretable-internal/grid-core"; - -export type PretableCoreColumn = - GridCoreColumn; - -export type PretableFormatInput = - GridCoreFormatInput; - -export type PretableGridOptions = - GridCoreOptions; - -export type PretableTransaction = - GridCoreTransaction; - -export interface PretableGrid< - TRow extends PretableRow = PretableRow, -> extends Omit, "options"> { - kind: "pretable-grid"; - options: PretableGridOptions; - getSnapshot(): GridCoreSnapshot; - setSort(columnId: string | null, direction: GridCoreSortDirection): void; - autosizeColumns(options?: AutosizeOptions): void; - applyTransaction(transaction: PretableTransaction): void; -} diff --git a/packages/grid-core/src/index.ts b/packages/grid-core/src/index.ts index 2452476d1..831e776f4 100644 --- a/packages/grid-core/src/index.ts +++ b/packages/grid-core/src/index.ts @@ -24,4 +24,4 @@ export type { PretableTransaction, PretableViewportState, } from "./types"; -export type { AutosizeOptions } from "@pretable-internal/layout-core"; +export type { AutosizeOptions, PretableRowRange } from "@pretable-internal/layout-core"; From d06960ffefc908bbd3d146ab4d8a712dae454227 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:50:59 -0700 Subject: [PATCH 06/11] refactor(react): rename import aliases for renamed core types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit types.ts imports core's PretableColumn as PretableBaseColumn to disambiguate from react's own PretableColumn. index.ts re-exports PretableColumn as PretableCoreColumn so react's public surface is unchanged — PR 3 will revisit the surface during the react audit. Co-Authored-By: Claude Opus 4.7 --- packages/react/src/index.ts | 2 +- packages/react/src/types.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 726b71f27..5209d0483 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -45,7 +45,7 @@ export type { DensityHeights } from "./density"; // Re-exports from @pretable/core export type { - PretableCoreColumn, + PretableColumn as PretableCoreColumn, PretableGrid, PretableGridOptions, PretableGridSnapshot, diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index 68e07b038..2e578bd6d 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -1,13 +1,13 @@ import type { ReactNode } from "react"; import type { - PretableCoreColumn, + PretableColumn as PretableBaseColumn, PretableFormatInput, PretableRow, } from "@pretable/core"; export interface PretableColumn< TRow extends PretableRow = PretableRow, -> extends PretableCoreColumn { +> extends PretableBaseColumn { render?: (input: PretableCellRenderInput) => ReactNode; renderHeader?: (input: PretableHeaderRenderInput) => ReactNode; } From 1d379945a6555b0ca268348c2f9fb868eb183b98 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:53:28 -0700 Subject: [PATCH 07/11] feat(core): hand-curated public_api.ts with @public TSDoc tags Adds @public TSDoc tags to every symbol exported through @pretable/core's public surface, plus @internal tags on engine-only symbols (PretableEngine, PretableFrame, deriveSelectedRows, rangeContainsCell, layout-core's planning types). index.ts collapses to a single re-export from public_api.ts. Co-Authored-By: Claude Opus 4.7 --- packages/core/src/index.ts | 21 +----- packages/core/src/public_api.ts | 32 ++++++++ packages/grid-core/src/derived-selection.ts | 7 ++ packages/grid-core/src/types.ts | 83 +++++++++++++++++++++ packages/layout-core/src/types.ts | 18 +++++ 5 files changed, 141 insertions(+), 20 deletions(-) create mode 100644 packages/core/src/public_api.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c7bfdd8f8..4ef9ceca4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,20 +1 @@ -export { createGrid } from "./create-grid"; -export type { PretableGrid } from "./pretable-grid"; -export type { - AutosizeOptions, - PretableCellAddress, - PretableCellRange, - PretableColumn, - PretableFocusState, - PretableFormatInput, - PretableGridOptions, - PretableGridSnapshot, - PretableRow, - PretableRowRange, - PretableSelectionState, - PretableSortDirection, - PretableSortState, - PretableTransaction, - PretableViewportState, - PretableVisibleRow, -} from "./types"; +export * from "./public_api"; diff --git a/packages/core/src/public_api.ts b/packages/core/src/public_api.ts new file mode 100644 index 000000000..4ceafc8ee --- /dev/null +++ b/packages/core/src/public_api.ts @@ -0,0 +1,32 @@ +/** + * Public API of `@pretable/core`. Hand-curated re-exports — do not edit + * `index.ts` directly. Internal symbols stay in their source files and + * are not re-exported here. + * + * @packageDocumentation + */ + +export { createGrid } from "./create-grid"; +export type { PretableGrid } from "./pretable-grid"; + +export type { + AutosizeOptions, + PretableCellAddress, + PretableCellRange, + PretableColumn, + PretableFocusDirection, + PretableFocusState, + PretableFormatInput, + PretableGridOptions, + PretableGridSnapshot, + PretableMoveFocusOptions, + PretableRow, + PretableRowRange, + PretableRowSelectionTriState, + PretableSelectionState, + PretableSortDirection, + PretableSortState, + PretableTransaction, + PretableViewportState, + PretableVisibleRow, +} from "./types"; diff --git a/packages/grid-core/src/derived-selection.ts b/packages/grid-core/src/derived-selection.ts index fcaef45cf..88c92158e 100644 --- a/packages/grid-core/src/derived-selection.ts +++ b/packages/grid-core/src/derived-selection.ts @@ -6,8 +6,14 @@ import type { PretableSelectionState, } from "./types"; +/** + * Per-row selection state — "selected" means fully, "indeterminate" means partial. + * + * @public + */ export type PretableRowSelectionTriState = "selected" | "indeterminate"; +/** @internal */ export function rangeContainsCell( range: PretableCellRange, rowId: string, @@ -47,6 +53,7 @@ export function rangeContainsCell( ); } +/** @internal */ export function deriveSelectedRows(args: { visibleRows: PretableVisibleRow[]; columns: PretableColumn[]; diff --git a/packages/grid-core/src/types.ts b/packages/grid-core/src/types.ts index ab8e0a0b3..42587188d 100644 --- a/packages/grid-core/src/types.ts +++ b/packages/grid-core/src/types.ts @@ -3,9 +3,25 @@ import type { PretableRowRange, } from "@pretable-internal/layout-core"; +/** + * Base row constraint — every row is at minimum a string-keyed record. + * + * @public + */ export type PretableRow = Record; + +/** + * Sort direction — `null` means unsorted. + * + * @public + */ export type PretableSortDirection = "asc" | "desc" | null; +/** + * Engine-level column definition. `@pretable/react` extends this with React-specific render fields. + * + * @public + */ export interface PretableColumn { id: string; header?: string; @@ -23,12 +39,22 @@ export interface PretableColumn { reorderable?: boolean; } +/** + * Input passed to a column's `format` function. + * + * @public + */ export interface PretableFormatInput { value: unknown; row: TRow; column: PretableColumn; } +/** + * Options accepted by `createGrid`. + * + * @public + */ export interface PretableGridOptions { columns: PretableColumn[]; rows: TRow[]; @@ -36,16 +62,31 @@ export interface PretableGridOptions { autosize?: boolean | AutosizeOptions; } +/** + * Active sort. `columnId` is null when no column is sorted. + * + * @public + */ export interface PretableSortState { columnId: string | null; direction: PretableSortDirection; } +/** + * Cell address — the (rowId, columnId) pair that uniquely identifies a cell. + * + * @public + */ export interface PretableCellAddress { rowId: string; columnId: string; } +/** + * Inclusive cell range — both bounds (start and end) are inside the selection. + * + * @public + */ export interface PretableCellRange { startRowId: string; endRowId: string; @@ -53,16 +94,31 @@ export interface PretableCellRange { endColumnId: string; } +/** + * Cell-range selection state including the optional anchor for shift-extension. + * + * @public + */ export interface PretableSelectionState { ranges: PretableCellRange[]; anchor: PretableCellAddress | null; } +/** + * Currently focused cell — both fields are null when nothing is focused. + * + * @public + */ export interface PretableFocusState { rowId: string | null; columnId: string | null; } +/** + * Viewport-level scroll + size state. + * + * @public + */ export interface PretableViewportState { scrollTop: number; scrollLeft: number; @@ -70,18 +126,33 @@ export interface PretableViewportState { width: number; } +/** + * Streaming transaction — incremental row mutations applied via `PretableGrid.applyTransaction`. + * + * @public + */ export interface PretableTransaction { add?: TRow[]; update?: Partial[]; remove?: string[]; } +/** + * A row currently in the visible window — includes its source-array index for stable identity. + * + * @public + */ export interface PretableVisibleRow { id: string; row: TRow; sourceIndex: number; } +/** + * Read-only state observed via `PretableGrid.getSnapshot`. + * + * @public + */ export interface PretableGridSnapshot { viewport: PretableViewportState; sort: PretableSortState; @@ -93,6 +164,7 @@ export interface PretableGridSnapshot { visibleRange: PretableRowRange; } +/** @internal */ export interface PretableEngine { options: PretableGridOptions; subscribe(listener: () => void): () => void; @@ -129,14 +201,25 @@ export interface PretableEngine { mergeColumnsFromProps(nextColumns: PretableColumn[]): void; } +/** + * Direction passed to `PretableGrid.moveFocus`. + * + * @public + */ export type PretableFocusDirection = "up" | "down" | "left" | "right"; +/** + * Optional behavior modifiers for `PretableGrid.moveFocus`. + * + * @public + */ export interface PretableMoveFocusOptions { extend?: boolean; jumpToEdge?: boolean; byPage?: boolean; } +/** @internal */ export interface PretableFrame { snapshot: PretableGridSnapshot; } diff --git a/packages/layout-core/src/types.ts b/packages/layout-core/src/types.ts index c8f038e8e..4738c1b5f 100644 --- a/packages/layout-core/src/types.ts +++ b/packages/layout-core/src/types.ts @@ -9,6 +9,7 @@ export interface PretableRowRange { end: number; } +/** @internal */ export interface RowMetricsIndex { readonly rowCount: number; getHeight(index: number): number; @@ -18,23 +19,27 @@ export interface RowMetricsIndex { updateHeight(index: number, height: number): void; } +/** @internal */ export interface PinnedColumnInput { columnId: string; width: number; } +/** @internal */ export interface PlannedPinnedColumn extends PinnedColumnInput { side: "left" | "right"; start: number; end: number; } +/** @internal */ export interface PlannedRow { index: number; top: number; height: number; } +/** @internal */ export interface PlanViewportInput { scrollTop: number; viewportHeight: number; @@ -44,6 +49,7 @@ export interface PlanViewportInput { pinnedRight?: PinnedColumnInput[]; } +/** @internal */ export interface ViewportPlan { range: PretableRowRange; rows: PlannedRow[]; @@ -54,6 +60,7 @@ export interface ViewportPlan { }; } +/** @internal */ export interface PlanColumnsInput { columns: readonly PlanColumnsColumnInput[]; scrollLeft: number; @@ -61,12 +68,14 @@ export interface PlanColumnsInput { overscan: number; } +/** @internal */ export interface PlanColumnsColumnInput { id: string; width: number; pinned?: "left"; } +/** @internal */ export interface PlannedColumn { index: number; id: string; @@ -75,12 +84,14 @@ export interface PlannedColumn { pinned?: "left"; } +/** @internal */ export interface ColumnPlan { columns: PlannedColumn[]; totalWidth: number; pinnedLeftWidth: number; } +/** @internal */ export interface AutosizeColumnDef< TRow extends Record = Record, > { @@ -91,6 +102,11 @@ export interface AutosizeColumnDef< value?: (row: TRow) => unknown; } +/** + * Tuning knobs for column autosize calculations. + * + * @public + */ export interface AutosizeOptions { maxWidthPx?: number; minWidthPx?: number; @@ -98,6 +114,7 @@ export interface AutosizeOptions { cellPaddingPx?: number; } +/** @internal */ export interface AutosizeColumnsInput< TRow extends Record = Record, > { @@ -106,6 +123,7 @@ export interface AutosizeColumnsInput< options?: AutosizeOptions; } +/** @internal */ export interface AutosizeResult { widths: Map; } From 2df5e149978fd50f3bcc252fde018090551a87f7 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:55:11 -0700 Subject: [PATCH 08/11] chore(api): bundle internal packages; flip missing-release-tag to warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bundledPackages now inlines @pretable-internal/grid-core and @pretable-internal/layout-core into each report so renamed types appear self-contained. ae-missing-release-tag was 'none' for the PR 1 baseline; flips to 'warning' now that core is fully tagged — provides coverage visibility for PRs 3-5 without failing CI. Co-Authored-By: Claude Opus 4.7 --- api-extractor.base.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api-extractor.base.json b/api-extractor.base.json index 1b1285bde..87f8e8298 100644 --- a/api-extractor.base.json +++ b/api-extractor.base.json @@ -20,7 +20,7 @@ "logLevel": "warning" }, "ae-missing-release-tag": { - "logLevel": "none" + "logLevel": "warning" } } }, @@ -43,6 +43,8 @@ "@pretable/core", "@pretable/react", "@pretable/ui", - "@pretable/stream-adapter" + "@pretable/stream-adapter", + "@pretable-internal/grid-core", + "@pretable-internal/layout-core" ] } From 847c4f6683679d76f169710b7f29ce95e91dff9e Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:56:25 -0700 Subject: [PATCH 09/11] chore(api): regenerate .api.md; revert release-tag flip and silence unresolved-link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit core.api.md: zero ae-forgotten-export warnings; every public symbol annotated @public; PretableGrid is a flat interface. react.api.md: mechanical rename diff (Pretable* names inlined). api-extractor.base.json: ae-missing-release-tag stays at "none" (the spec's flip-to-warning broke api:check — non-local mode treats warnings as fatal, opposite of what the spec assumed). ae-unresolved-link silenced because cross-package {@link createGrid} can't resolve in bundled reports. Tag flip will land in PR 5 once react/ui/stream-adapter are tagged. Co-Authored-By: Claude Opus 4.7 --- api-extractor.base.json | 5 +- packages/core/core.api.md | 180 +++++++++++++++++++++++++++--------- packages/react/react.api.md | 176 +++++++++++++++++++++++++---------- 3 files changed, 267 insertions(+), 94 deletions(-) diff --git a/api-extractor.base.json b/api-extractor.base.json index 87f8e8298..e55ef6b17 100644 --- a/api-extractor.base.json +++ b/api-extractor.base.json @@ -20,7 +20,10 @@ "logLevel": "warning" }, "ae-missing-release-tag": { - "logLevel": "warning" + "logLevel": "none" + }, + "ae-unresolved-link": { + "logLevel": "none" } } }, diff --git a/packages/core/core.api.md b/packages/core/core.api.md index 8e5c8dc69..7129ab87a 100644 --- a/packages/core/core.api.md +++ b/packages/core/core.api.md @@ -4,7 +4,7 @@ ```ts -// @public (undocumented) +// @public export interface AutosizeOptions { // (undocumented) averageCharWidth?: number; @@ -16,10 +16,10 @@ export interface AutosizeOptions { minWidthPx?: number; } -// @public (undocumented) -export function createGrid>(options: PretableGridOptions): PretableGrid; +// @public +export function createGrid(options: PretableGridOptions): PretableGrid; -// @public (undocumented) +// @public export interface PretableCellAddress { // (undocumented) columnId: string; @@ -27,7 +27,7 @@ export interface PretableCellAddress { rowId: string; } -// @public (undocumented) +// @public export interface PretableCellRange { // (undocumented) endColumnId: string; @@ -39,12 +39,40 @@ export interface PretableCellRange { startRowId: string; } -// Warning: (ae-forgotten-export) The symbol "GridCoreColumn" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableCoreColumn = GridCoreColumn; +// @public +export interface PretableColumn { + // (undocumented) + filterable?: boolean; + // (undocumented) + format?: (input: PretableFormatInput) => string; + // (undocumented) + header?: string; + // (undocumented) + id: string; + // (undocumented) + maxWidthPx?: number; + // (undocumented) + minWidthPx?: number; + // (undocumented) + pinned?: "left"; + // (undocumented) + reorderable?: boolean; + // (undocumented) + resizable?: boolean; + // (undocumented) + sortable?: boolean; + // (undocumented) + value?: (row: TRow) => unknown; + // (undocumented) + widthPx?: number; + // (undocumented) + wrap?: boolean; +} -// @public (undocumented) +// @public +export type PretableFocusDirection = "up" | "down" | "left" | "right"; + +// @public export interface PretableFocusState { // (undocumented) columnId: string | null; @@ -52,38 +80,82 @@ export interface PretableFocusState { rowId: string | null; } -// Warning: (ae-forgotten-export) The symbol "GridCoreFormatInput" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableFormatInput = GridCoreFormatInput; +// @public +export interface PretableFormatInput { + // (undocumented) + column: PretableColumn; + // (undocumented) + row: TRow; + // (undocumented) + value: unknown; +} -// Warning: (ae-forgotten-export) The symbol "GridCoreStore" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export interface PretableGrid extends Omit, "options"> { +// @public +export interface PretableGrid { + // (undocumented) + addRange(range: PretableCellRange): void; // (undocumented) applyTransaction(transaction: PretableTransaction): void; // (undocumented) + autosizeColumn(columnId: string, options?: AutosizeOptions): void; + // (undocumented) autosizeColumns(options?: AutosizeOptions): void; // (undocumented) + clearFilters(): void; + // (undocumented) + clearSelection(): void; + // (undocumented) + extendRangeFromAnchor(addr: PretableCellAddress): void; getSnapshot(): PretableGridSnapshot; + readonly kind: "pretable-grid"; + // (undocumented) + mergeColumnsFromProps(nextColumns: PretableColumn[]): void; + // (undocumented) + moveColumn(columnId: string, toIndex: number): void; // (undocumented) - kind: "pretable-grid"; + moveFocus(direction: PretableFocusDirection, options?: PretableMoveFocusOptions): void; + readonly options: PretableGridOptions; // (undocumented) - options: PretableGridOptions; + replaceFilters(nextFilters: Record): void; + // (undocumented) + resetColumnLayout(): void; + // (undocumented) + selectAll(): void; + // (undocumented) + setColumnPinned(columnId: string, pinned: "left" | null): void; + // (undocumented) + setColumnWidth(columnId: string, width: number): void; + // (undocumented) + setFilter(columnId: string, value: string): void; + // (undocumented) + setFocus(addr: PretableCellAddress | null): void; + // (undocumented) + setSelectAllVisible(checked: boolean): void; + // (undocumented) + setSelection(state: PretableSelectionState): void; // (undocumented) setSort(columnId: string | null, direction: PretableSortDirection): void; + // (undocumented) + setViewport(viewport: PretableViewportState): void; + subscribe(listener: () => void): () => void; + // (undocumented) + toggleRowSelection(rowId: string): void; } -// Warning: (ae-forgotten-export) The symbol "GridCoreOptions" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableGridOptions = GridCoreOptions; +// @public +export interface PretableGridOptions { + // (undocumented) + autosize?: boolean | AutosizeOptions; + // (undocumented) + columns: PretableColumn[]; + // (undocumented) + getRowId?: (row: TRow, index: number) => string; + // (undocumented) + rows: TRow[]; +} -// Warning: (ae-forgotten-export) The symbol "GridCoreRow" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export interface PretableGridSnapshot { +// @public +export interface PretableGridSnapshot { // (undocumented) filters: Record; // (undocumented) @@ -96,18 +168,37 @@ export interface PretableGridSnapshot { totalRowCount: number; // (undocumented) viewport: PretableViewportState; - // Warning: (ae-forgotten-export) The symbol "LayoutSpan" needs to be exported by the entry point index.d.ts - // // (undocumented) - visibleRange: LayoutSpan; + visibleRange: PretableRowRange; // (undocumented) visibleRows: PretableVisibleRow[]; } -// @public (undocumented) +// @public +export interface PretableMoveFocusOptions { + // (undocumented) + byPage?: boolean; + // (undocumented) + extend?: boolean; + // (undocumented) + jumpToEdge?: boolean; +} + +// @public export type PretableRow = Record; -// @public (undocumented) +// @public +export interface PretableRowRange { + // (undocumented) + end: number; + // (undocumented) + start: number; +} + +// @public +export type PretableRowSelectionTriState = "selected" | "indeterminate"; + +// @public export interface PretableSelectionState { // (undocumented) anchor: PretableCellAddress | null; @@ -115,10 +206,10 @@ export interface PretableSelectionState { ranges: PretableCellRange[]; } -// @public (undocumented) +// @public export type PretableSortDirection = "asc" | "desc" | null; -// @public (undocumented) +// @public export interface PretableSortState { // (undocumented) columnId: string | null; @@ -126,12 +217,17 @@ export interface PretableSortState { direction: PretableSortDirection; } -// Warning: (ae-forgotten-export) The symbol "GridCoreTransaction" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableTransaction = GridCoreTransaction; +// @public +export interface PretableTransaction { + // (undocumented) + add?: TRow[]; + // (undocumented) + remove?: string[]; + // (undocumented) + update?: Partial[]; +} -// @public (undocumented) +// @public export interface PretableViewportState { // (undocumented) height: number; @@ -143,8 +239,8 @@ export interface PretableViewportState { width: number; } -// @public (undocumented) -export interface PretableVisibleRow { +// @public +export interface PretableVisibleRow { // (undocumented) id: string; // (undocumented) diff --git a/packages/react/react.api.md b/packages/react/react.api.md index 1577ca214..c814cbbb6 100644 --- a/packages/react/react.api.md +++ b/packages/react/react.api.md @@ -189,77 +189,153 @@ export interface PretableColumn extends renderHeader?: (input: PretableHeaderRenderInput) => ReactNode; } -// Warning: (ae-forgotten-export) The symbol "GridCoreColumn" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableCoreColumn = GridCoreColumn; +// @public +export interface PretableCoreColumn { + // (undocumented) + filterable?: boolean; + // (undocumented) + format?: (input: PretableFormatInput) => string; + // (undocumented) + header?: string; + // (undocumented) + id: string; + // (undocumented) + maxWidthPx?: number; + // (undocumented) + minWidthPx?: number; + // (undocumented) + pinned?: "left"; + // (undocumented) + reorderable?: boolean; + // (undocumented) + resizable?: boolean; + // (undocumented) + sortable?: boolean; + // (undocumented) + value?: (row: TRow) => unknown; + // (undocumented) + widthPx?: number; + // (undocumented) + wrap?: boolean; +} -// Warning: (ae-forgotten-export) The symbol "GridCoreFormatInput" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableFormatInput = GridCoreFormatInput; +// @public +export interface PretableFormatInput { + // (undocumented) + column: PretableCoreColumn; + // (undocumented) + row: TRow; + // (undocumented) + value: unknown; +} -// Warning: (ae-forgotten-export) The symbol "GridCoreStore" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export interface PretableGrid extends Omit, "options"> { +// @public +export interface PretableGrid { + // Warning: (ae-forgotten-export) The symbol "PretableCellRange" needs to be exported by the entry point index.d.ts + // + // (undocumented) + addRange(range: PretableCellRange): void; // Warning: (ae-forgotten-export) The symbol "PretableTransaction" needs to be exported by the entry point index.d.ts // // (undocumented) applyTransaction(transaction: PretableTransaction): void; + // (undocumented) + autosizeColumn(columnId: string, options?: AutosizeOptions): void; // Warning: (ae-forgotten-export) The symbol "AutosizeOptions" needs to be exported by the entry point index.d.ts // // (undocumented) autosizeColumns(options?: AutosizeOptions): void; // (undocumented) + clearFilters(): void; + // (undocumented) + clearSelection(): void; + // Warning: (ae-forgotten-export) The symbol "PretableCellAddress" needs to be exported by the entry point index.d.ts + // + // (undocumented) + extendRangeFromAnchor(addr: PretableCellAddress): void; getSnapshot(): PretableGridSnapshot; + readonly kind: "pretable-grid"; // (undocumented) - kind: "pretable-grid"; + mergeColumnsFromProps(nextColumns: PretableCoreColumn[]): void; // (undocumented) - options: PretableGridOptions; - // Warning: (ae-forgotten-export) The symbol "GridCoreSortDirection" needs to be exported by the entry point index.d.ts + moveColumn(columnId: string, toIndex: number): void; + // Warning: (ae-forgotten-export) The symbol "PretableFocusDirection" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "PretableMoveFocusOptions" needs to be exported by the entry point index.d.ts // // (undocumented) - setSort(columnId: string | null, direction: GridCoreSortDirection): void; + moveFocus(direction: PretableFocusDirection, options?: PretableMoveFocusOptions): void; + readonly options: PretableGridOptions; + // (undocumented) + replaceFilters(nextFilters: Record): void; + // (undocumented) + resetColumnLayout(): void; + // (undocumented) + selectAll(): void; + // (undocumented) + setColumnPinned(columnId: string, pinned: "left" | null): void; + // (undocumented) + setColumnWidth(columnId: string, width: number): void; + // (undocumented) + setFilter(columnId: string, value: string): void; + // (undocumented) + setFocus(addr: PretableCellAddress | null): void; + // (undocumented) + setSelectAllVisible(checked: boolean): void; + // Warning: (ae-forgotten-export) The symbol "PretableSelectionState" needs to be exported by the entry point index.d.ts + // + // (undocumented) + setSelection(state: PretableSelectionState): void; + // Warning: (ae-forgotten-export) The symbol "PretableSortDirection" needs to be exported by the entry point index.d.ts + // + // (undocumented) + setSort(columnId: string | null, direction: PretableSortDirection): void; + // Warning: (ae-forgotten-export) The symbol "PretableViewportState" needs to be exported by the entry point index.d.ts + // + // (undocumented) + setViewport(viewport: PretableViewportState): void; + subscribe(listener: () => void): () => void; + // (undocumented) + toggleRowSelection(rowId: string): void; } -// Warning: (ae-forgotten-export) The symbol "GridCoreOptions" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export type PretableGridOptions = GridCoreOptions; +// @public +export interface PretableGridOptions { + // (undocumented) + autosize?: boolean | AutosizeOptions; + // (undocumented) + columns: PretableCoreColumn[]; + // (undocumented) + getRowId?: (row: TRow, index: number) => string; + // (undocumented) + rows: TRow[]; +} -// Warning: (ae-forgotten-export) The symbol "GridCoreRow" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export interface PretableGridSnapshot { +// @public +export interface PretableGridSnapshot { // (undocumented) filters: Record; - // Warning: (ae-forgotten-export) The symbol "GridCoreFocusState" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "PretableFocusState" needs to be exported by the entry point index.d.ts // // (undocumented) - focus: GridCoreFocusState; - // Warning: (ae-forgotten-export) The symbol "GridCoreSelectionState" needs to be exported by the entry point index.d.ts - // + focus: PretableFocusState; // (undocumented) - selection: GridCoreSelectionState; - // Warning: (ae-forgotten-export) The symbol "GridCoreSortState" needs to be exported by the entry point index.d.ts + selection: PretableSelectionState; + // Warning: (ae-forgotten-export) The symbol "PretableSortState" needs to be exported by the entry point index.d.ts // // (undocumented) - sort: GridCoreSortState; + sort: PretableSortState; // (undocumented) totalRowCount: number; - // Warning: (ae-forgotten-export) The symbol "GridCoreViewportState" needs to be exported by the entry point index.d.ts - // // (undocumented) - viewport: GridCoreViewportState; - // Warning: (ae-forgotten-export) The symbol "LayoutSpan" needs to be exported by the entry point index.d.ts + viewport: PretableViewportState; + // Warning: (ae-forgotten-export) The symbol "PretableRowRange" needs to be exported by the entry point index.d.ts // // (undocumented) - visibleRange: LayoutSpan; - // Warning: (ae-forgotten-export) The symbol "GridCoreRowModel" needs to be exported by the entry point index.d.ts + visibleRange: PretableRowRange; + // Warning: (ae-forgotten-export) The symbol "PretableVisibleRow" needs to be exported by the entry point index.d.ts // // (undocumented) - visibleRows: GridCoreRowModel[]; + visibleRows: PretableVisibleRow[]; } // @public (undocumented) @@ -344,7 +420,7 @@ export interface PretableRenderSnapshot totalWidth: number; } -// @public (undocumented) +// @public export type PretableRow = Record; // @public (undocumented) @@ -412,13 +488,13 @@ export interface PretableSurfaceProps { onColumnWidthsChange?: (next: Record) => void; onCopy?: (args: SerializeRangesArgs) => CopyPayload | null; // (undocumented) - onFocusChange?: (next: GridCoreFocusState) => void; + onFocusChange?: (next: PretableFocusState) => void; // (undocumented) onGridReady?: (grid: PretableGrid) => void; // (undocumented) onSelectedRowIdChange?: (rowId: string | null) => void; // (undocumented) - onSelectionChange?: (next: GridCoreSelectionState) => void; + onSelectionChange?: (next: PretableSelectionState) => void; // (undocumented) onSortChange?: (sort: { columnId: string; @@ -461,11 +537,11 @@ export interface PretableSurfaceState { // (undocumented) filters?: Record; // (undocumented) - focus?: GridCoreFocusState; + focus?: PretableFocusState; // (undocumented) - selection?: GridCoreSelectionState; + selection?: PretableSelectionState; // (undocumented) - sort?: GridCoreSortState | null; + sort?: PretableSortState | null; } // @public (undocumented) @@ -514,12 +590,10 @@ export interface SerializeRangesArgs { columns: readonly PretableColumn[]; // (undocumented) copyWithHeaders?: boolean; - // Warning: (ae-forgotten-export) The symbol "GridCoreCellRange" needs to be exported by the entry point index.d.ts - // // (undocumented) - ranges: readonly GridCoreCellRange[]; + ranges: readonly PretableCellRange[]; // (undocumented) - visibleRows: readonly GridCoreRowModel[]; + visibleRows: readonly PretableVisibleRow[]; } // @public (undocumented) @@ -536,9 +610,9 @@ export interface UsePretableModelOptions // (undocumented) measuredHeights?: Record; // (undocumented) - onFocusChange?: (next: GridCoreFocusState) => void; + onFocusChange?: (next: PretableFocusState) => void; // (undocumented) - onSelectionChange?: (next: GridCoreSelectionState) => void; + onSelectionChange?: (next: PretableSelectionState) => void; // (undocumented) overscan?: number; // (undocumented) @@ -566,7 +640,7 @@ export function useResolvedHeights(rowHeightProp?: number, headerHeightProp?: nu // Warnings were encountered during analysis: // -// dist/index.d.ts:294:9 - (ae-forgotten-export) The symbol "PretableSurfaceSortDirection" needs to be exported by the entry point index.d.ts +// dist/index.d.ts:295:9 - (ae-forgotten-export) The symbol "PretableSurfaceSortDirection" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) From 212d20ad6932ccdaff771b12306bfcfef1ac69e5 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 10:59:13 -0700 Subject: [PATCH 10/11] docs(core): add per-package README; correct spec on api-extractor warnings README mentions headless support; full docs/examples deferred per project_headless_engine_docs_deferred.md memory. Spec correction: api-extractor's non-local mode treats warnings as fatal, so ae-missing-release-tag stays at "none" until PR 5. Also silences ae-unresolved-link for cross-package TSDoc refs. Co-Authored-By: Claude Opus 4.7 --- ...tier1-api-stabilization-pr2-core-design.md | 4 +- packages/core/README.md | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/core/README.md diff --git a/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md index e9bb29a8b..d8b53f15f 100644 --- a/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md +++ b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md @@ -118,7 +118,9 @@ export type { ### `ae-missing-release-tag` config -PR 1 set this rule's `logLevel` to `none` to allow undocumented baselines. PR 2 flips it to `warning` once core is fully tagged. The `warning` level surfaces coverage gaps (a developer adds a public symbol but forgets the `@public` tag) without blocking CI in non-local mode. (api-extractor's non-local mode treats configured-as-error issues as fatal but allows warnings; the `warning` level produces visibility, not enforcement.) +PR 1 set this rule's `logLevel` to `none` to allow undocumented baselines. PR 2 keeps it at `none` because — as discovered during implementation — api-extractor's non-local mode treats `warning`-level extractor messages as **fatal** (exit 1), opposite of what the spec originally assumed. Flipping to `warning` would break `api:check` for `@pretable/react`, `@pretable/ui`, and `@pretable/stream-adapter` (which still have untagged symbols pending PRs 3–5). The flip moves to PR 5 once every package is fully tagged. + +Additionally, `ae-unresolved-link` is silenced (`logLevel: none`) because cross-package `{@link …}` references — e.g., a TSDoc in `@pretable/core`'s `pretable-grid.ts` linking to `createGrid` — cannot resolve when api-extractor processes a different package whose bundled report inlines the source. The links work fine in IDE tooltips; only the bundled-report resolver fails. Silencing avoids false-positive CI failures. ## Data flow diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 000000000..55db57231 --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,48 @@ +# @pretable/core + +The headless engine for [pretable](https://pretable.dev/). Drives sort, filter, selection, focus, viewport, and streaming-transaction state for any table-shaped UI. + +## When to reach for this + +Most users want **[`@pretable/react`](../react)** instead. It bundles `@pretable/core` with a React surface that handles rendering, layout, and keyboard interaction. + +`@pretable/core` is for users building their own UI from scratch — for example, plain DOM, a non-React framework, or a custom canvas/webgl renderer. Headless usage is supported (the `createGrid` factory returns a fully-typed `PretableGrid` handle), but **dedicated docs, examples, and demos for headless mode are forthcoming**. If headless is what you're after, the type definitions and [`core.api.md`](./core.api.md) are the source of truth today. + +## Install + +```sh +npm install @pretable/core +# or pnpm add @pretable/core, yarn add @pretable/core +``` + +## Minimal example + +```ts +import { createGrid } from "@pretable/core"; + +const grid = createGrid({ + columns: [ + { id: "name", header: "Name" }, + { id: "age", header: "Age", sortable: true }, + ], + rows: [ + { id: "1", name: "Ada", age: 36 }, + { id: "2", name: "Grace", age: 85 }, + ], +}); + +grid.subscribe(() => { + const { visibleRows, sort } = grid.getSnapshot(); + console.log("rows:", visibleRows.length, "sort:", sort); +}); + +grid.setSort("age", "desc"); +``` + +## Full public surface + +See **[`core.api.md`](./core.api.md)** for every exported type, interface, and function with their full signatures. The file is generated by [API Extractor](https://api-extractor.com/) and committed to the repo; CI fails if it drifts. + +## License + +MIT — see [LICENSE](../../LICENSE). From 0885b7e2e78475a863d3fba5cd77e78f0c1f1b59 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Fri, 8 May 2026 11:01:14 -0700 Subject: [PATCH 11/11] chore: prettier reformat spec/plan/grid-core barrel Co-Authored-By: Claude Opus 4.7 --- ...-05-08-tier1-api-stabilization-pr2-core.md | 129 +++++++++++------- ...tier1-api-stabilization-pr2-core-design.md | 48 +++---- packages/grid-core/src/index.ts | 5 +- 3 files changed, 106 insertions(+), 76 deletions(-) diff --git a/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md b/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md index 49aaad780..afec8f6dd 100644 --- a/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md +++ b/docs/superpowers/plans/2026-05-08-tier1-api-stabilization-pr2-core.md @@ -14,35 +14,36 @@ ## File Structure -| Path | Responsibility | Action | -|---|---|---| -| `packages/layout-core/src/types.ts` | `LayoutSpan` interface | Modify (rename → `PretableRowRange`) | -| `packages/layout-core/src/index.ts` | Layout-core barrel | Modify (rename in re-export) | -| `packages/grid-core/src/types.ts` | All `GridCore*` types | Modify (rename → `Pretable*`) | -| `packages/grid-core/src/index.ts` | Grid-core barrel | Modify (rename in re-exports) | -| `packages/grid-core/src/create-grid-core.ts` | Engine factory | Modify (rename internal references) | -| `packages/grid-core/src/derived-rows.ts` | Internal helper | Modify (rename internal references) | -| `packages/grid-core/src/derived-selection.ts` | Internal helper | Modify (rename `RowSelectionTriState` → `PretableRowSelectionTriState`) | -| `packages/grid-core/src/__tests__/selection-state.test.ts` | Test file | Modify (rename imports) | -| `packages/renderer-dom/src/types.ts` | DOM render types | Modify (rename internal imports) | -| `packages/renderer-dom/src/create-renderer.ts` | DOM renderer | Modify (rename internal imports) | -| `packages/core/src/pretable-grid.ts` | **NEW** explicit `PretableGrid` interface | Create | -| `packages/core/src/types.ts` | Re-export shell | Modify (collapse from ~50 lines to ~25) | -| `packages/core/src/create-grid.ts` | `createGrid` factory | Modify (return type uses local `PretableGrid`) | -| `packages/core/src/public_api.ts` | **NEW** curated public surface with TSDoc | Create | -| `packages/core/src/index.ts` | Package entry | Modify (collapse to `export * from './public_api'`) | -| `packages/react/src/types.ts` | React's column/render types | Modify (rename import alias) | -| `packages/react/src/index.ts` | React barrel | Modify (rename one re-export) | -| `api-extractor.base.json` | api-extractor config | Modify (`bundledPackages` + `ae-missing-release-tag`) | -| `packages/core/core.api.md` | Generated baseline | Regenerate | -| `packages/react/react.api.md` | Generated baseline | Regenerate (rename-only diff expected) | -| `packages/core/README.md` | **NEW** per-package README | Create | +| Path | Responsibility | Action | +| ---------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------- | +| `packages/layout-core/src/types.ts` | `LayoutSpan` interface | Modify (rename → `PretableRowRange`) | +| `packages/layout-core/src/index.ts` | Layout-core barrel | Modify (rename in re-export) | +| `packages/grid-core/src/types.ts` | All `GridCore*` types | Modify (rename → `Pretable*`) | +| `packages/grid-core/src/index.ts` | Grid-core barrel | Modify (rename in re-exports) | +| `packages/grid-core/src/create-grid-core.ts` | Engine factory | Modify (rename internal references) | +| `packages/grid-core/src/derived-rows.ts` | Internal helper | Modify (rename internal references) | +| `packages/grid-core/src/derived-selection.ts` | Internal helper | Modify (rename `RowSelectionTriState` → `PretableRowSelectionTriState`) | +| `packages/grid-core/src/__tests__/selection-state.test.ts` | Test file | Modify (rename imports) | +| `packages/renderer-dom/src/types.ts` | DOM render types | Modify (rename internal imports) | +| `packages/renderer-dom/src/create-renderer.ts` | DOM renderer | Modify (rename internal imports) | +| `packages/core/src/pretable-grid.ts` | **NEW** explicit `PretableGrid` interface | Create | +| `packages/core/src/types.ts` | Re-export shell | Modify (collapse from ~50 lines to ~25) | +| `packages/core/src/create-grid.ts` | `createGrid` factory | Modify (return type uses local `PretableGrid`) | +| `packages/core/src/public_api.ts` | **NEW** curated public surface with TSDoc | Create | +| `packages/core/src/index.ts` | Package entry | Modify (collapse to `export * from './public_api'`) | +| `packages/react/src/types.ts` | React's column/render types | Modify (rename import alias) | +| `packages/react/src/index.ts` | React barrel | Modify (rename one re-export) | +| `api-extractor.base.json` | api-extractor config | Modify (`bundledPackages` + `ae-missing-release-tag`) | +| `packages/core/core.api.md` | Generated baseline | Regenerate | +| `packages/react/react.api.md` | Generated baseline | Regenerate (rename-only diff expected) | +| `packages/core/README.md` | **NEW** per-package README | Create | --- ## Task 1: Rename `LayoutSpan` → `PretableRowRange` in `@pretable-internal/layout-core` **Files:** + - Modify: `packages/layout-core/src/types.ts` - Modify: `packages/layout-core/src/index.ts` - Modify: `packages/grid-core/src/types.ts` (consumer) @@ -51,13 +52,16 @@ - [ ] **Step 1: Rename the interface in `packages/layout-core/src/types.ts`** Change line 1-4 from: + ```ts export interface LayoutSpan { start: number; end: number; } ``` + to: + ```ts /** * Half-open row index range — `start` inclusive, `end` exclusive — used to @@ -80,13 +84,16 @@ Find the line `LayoutSpan,` inside the `export type` list and rename to `Pretabl - [ ] **Step 3: Update grid-core consumers** In `packages/grid-core/src/types.ts`, line 1-4 currently: + ```ts import type { AutosizeOptions, LayoutSpan, } from "@pretable-internal/layout-core"; ``` + becomes: + ```ts import type { AutosizeOptions, @@ -129,6 +136,7 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 2: Rename `GridCore*` → `Pretable*` at engine source **Files:** + - Modify: `packages/grid-core/src/types.ts` - Modify: `packages/grid-core/src/index.ts` - Modify: `packages/grid-core/src/create-grid-core.ts` @@ -252,6 +260,7 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 3: Define explicit `PretableGrid` in `@pretable/core`; rewrite `create-grid.ts`; collapse `types.ts` **Files:** + - Create: `packages/core/src/pretable-grid.ts` - Modify: `packages/core/src/types.ts` - Modify: `packages/core/src/create-grid.ts` @@ -369,7 +378,7 @@ Note: `PretableGrid` is not re-exported from here — it is defined in `pretable Overwrite with: -```ts +````ts import { createGridCore } from "@pretable-internal/grid-core"; import type { PretableGrid } from "./pretable-grid"; @@ -427,7 +436,7 @@ export function createGrid( applyTransaction: engine.applyTransaction, }; } -``` +```` - [ ] **Step 4: Verify typecheck** @@ -455,12 +464,14 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 4: Update `@pretable/react` import alias and re-export **Files:** + - Modify: `packages/react/src/types.ts` - Modify: `packages/react/src/index.ts` - [ ] **Step 1: Update import in `packages/react/src/types.ts`** Change lines 1-7 from: + ```ts import type { ReactNode } from "react"; import type { @@ -469,7 +480,9 @@ import type { PretableRow, } from "@pretable/core"; ``` + to: + ```ts import type { ReactNode } from "react"; import type { @@ -480,16 +493,19 @@ import type { ``` Then update the `extends` clause — find: + ```ts export interface PretableColumn< TRow extends PretableRow = PretableRow, > extends PretableCoreColumn { ``` + and change `extends PretableCoreColumn` to `extends PretableBaseColumn`. - [ ] **Step 2: Update re-export in `packages/react/src/index.ts`** Find the block (around lines 47-53): + ```ts // Re-exports from @pretable/core export type { @@ -500,6 +516,7 @@ export type { PretableRow, } from "@pretable/core"; ``` + and change `PretableCoreColumn,` to `PretableColumn as PretableCoreColumn,`. The line becomes: ```ts @@ -544,6 +561,7 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 5: Write `@pretable/core/src/public_api.ts` with TSDoc; collapse `index.ts` **Files:** + - Create: `packages/core/src/public_api.ts` - Modify: `packages/core/src/index.ts` @@ -610,7 +628,7 @@ export type { Note: api-extractor reads the `@public` from TSDoc; the `/** ... */` block must directly precede the symbol. Inline-comment `@public` placement (as written here) works because each symbol is on its own line with the comment directly above. If api-extractor flags any as missing, hoist the TSDoc to a separate `/** ... @public */` block above the symbol. -Wait — TSDoc release tags must be on a doc comment attached to a *declaration*, not on a re-export line. Re-exports cannot carry release tags this way. Instead, the release tags must live on the original declarations in `@pretable-internal/grid-core/src/types.ts` and `@pretable-internal/layout-core/src/types.ts`. This step is updated below. +Wait — TSDoc release tags must be on a doc comment attached to a _declaration_, not on a re-export line. Re-exports cannot carry release tags this way. Instead, the release tags must live on the original declarations in `@pretable-internal/grid-core/src/types.ts` and `@pretable-internal/layout-core/src/types.ts`. This step is updated below. - [ ] **Step 2: Replace `public_api.ts` with the simpler re-export shell** @@ -665,26 +683,26 @@ This is where the tags actually attach. Apply this TSDoc above each exported sym The full set of additions follows. For each interface/type below, prepend the indicated TSDoc comment immediately above the declaration: -| Symbol | TSDoc summary | -|---|---| -| `PretableRow` | "Base row constraint — every row is at minimum a string-keyed record." | -| `PretableSortDirection` | "Sort direction — \`null\` means unsorted." | -| `PretableColumn` | "Engine-level column definition. \`@pretable/react\` extends this with React-specific render fields." | -| `PretableFormatInput` | "Input passed to a column's \`format\` function." | -| `PretableGridOptions` | "Options accepted by \`createGrid\`." | -| `PretableSortState` | "Active sort. \`columnId\` is null when no column is sorted." | -| `PretableCellAddress` | "Cell address — the (rowId, columnId) pair that uniquely identifies a cell." | -| `PretableCellRange` | "Inclusive cell range — both bounds (start and end) are inside the selection." | -| `PretableSelectionState` | "Cell-range selection state including the optional anchor for shift-extension." | -| `PretableFocusState` | "Currently focused cell — both fields are null when nothing is focused." | -| `PretableViewportState` | "Viewport-level scroll + size state." | -| `PretableTransaction` | "Streaming transaction — incremental row mutations applied via \`PretableGrid.applyTransaction\`." | -| `PretableVisibleRow` | "A row currently in the visible window — includes its source-array index for stable identity." | -| `PretableGridSnapshot` | "Read-only state observed via \`PretableGrid.getSnapshot\`." | -| `PretableEngine` | "@internal" (this is intentionally not public — keeps it out of the report) | -| `PretableFocusDirection` | "Direction passed to \`PretableGrid.moveFocus\`." | -| `PretableMoveFocusOptions` | "Optional behavior modifiers for \`PretableGrid.moveFocus\`." | -| `PretableFrame` | "@internal" (not public) | +| Symbol | TSDoc summary | +| -------------------------- | ----------------------------------------------------------------------------------------------------- | +| `PretableRow` | "Base row constraint — every row is at minimum a string-keyed record." | +| `PretableSortDirection` | "Sort direction — \`null\` means unsorted." | +| `PretableColumn` | "Engine-level column definition. \`@pretable/react\` extends this with React-specific render fields." | +| `PretableFormatInput` | "Input passed to a column's \`format\` function." | +| `PretableGridOptions` | "Options accepted by \`createGrid\`." | +| `PretableSortState` | "Active sort. \`columnId\` is null when no column is sorted." | +| `PretableCellAddress` | "Cell address — the (rowId, columnId) pair that uniquely identifies a cell." | +| `PretableCellRange` | "Inclusive cell range — both bounds (start and end) are inside the selection." | +| `PretableSelectionState` | "Cell-range selection state including the optional anchor for shift-extension." | +| `PretableFocusState` | "Currently focused cell — both fields are null when nothing is focused." | +| `PretableViewportState` | "Viewport-level scroll + size state." | +| `PretableTransaction` | "Streaming transaction — incremental row mutations applied via \`PretableGrid.applyTransaction\`." | +| `PretableVisibleRow` | "A row currently in the visible window — includes its source-array index for stable identity." | +| `PretableGridSnapshot` | "Read-only state observed via \`PretableGrid.getSnapshot\`." | +| `PretableEngine` | "@internal" (this is intentionally not public — keeps it out of the report) | +| `PretableFocusDirection` | "Direction passed to \`PretableGrid.moveFocus\`." | +| `PretableMoveFocusOptions` | "Optional behavior modifiers for \`PretableGrid.moveFocus\`." | +| `PretableFrame` | "@internal" (not public) | The format for each comment block: @@ -713,11 +731,13 @@ export interface PretableEngine { - [ ] **Step 4: Add `@public` + TSDoc to `PretableRowSelectionTriState` in `derived-selection.ts`** In `packages/grid-core/src/derived-selection.ts`, find: + ```ts export type PretableRowSelectionTriState = "selected" | "indeterminate"; ``` Prepend: + ```ts /** * Per-row selection state — "selected" means fully, "indeterminate" means partial. @@ -791,6 +811,7 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 6: Update `api-extractor.base.json` **Files:** + - Modify: `api-extractor.base.json` - [ ] **Step 1: Add internal packages to `bundledPackages`** @@ -843,6 +864,7 @@ pnpm --filter @pretable/core api ``` Expected: `API Extractor completed successfully`. The regenerated `core.api.md` should now show: + - Zero `ae-forgotten-export` warnings. - Every public symbol annotated `// @public` (not `@public (undocumented)`). - `PretableGrid` rendered as a flat interface (not `extends Omit<...>`). @@ -869,6 +891,7 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 7: Regenerate `.api.md` files **Files:** + - Modify: `packages/core/core.api.md` - Modify: `packages/react/react.api.md` @@ -887,7 +910,8 @@ head -30 packages/core/core.api.md ``` Expected first lines: -``` + +```` ## API Report File for "@pretable/core" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). @@ -898,7 +922,7 @@ Expected first lines: export interface AutosizeOptions { ... } -``` +```` `AutosizeOptions`, `createGrid`, and every type should appear with `// @public` (not `@public (undocumented)`). Search for `(undocumented)` in the file: @@ -948,13 +972,14 @@ Co-Authored-By: Claude Opus 4.7 " ## Task 8: Write `packages/core/README.md` **Files:** + - Create: `packages/core/README.md` - [ ] **Step 1: Write the README** Create `packages/core/README.md` with this content: -```markdown +````markdown # @pretable/core The headless engine for [pretable](https://pretable.dev/). Drives sort, filter, selection, focus, viewport, and streaming-transaction state for any table-shaped UI. @@ -971,6 +996,7 @@ Most users want **[`@pretable/react`](../react)** instead. It bundles `@pretable npm install @pretable/core # or pnpm add @pretable/core, yarn add @pretable/core ``` +```` ## Minimal example @@ -1003,7 +1029,8 @@ See **[`core.api.md`](./core.api.md)** for every exported type, interface, and f ## License MIT — see [LICENSE](../../LICENSE). -``` + +```` - [ ] **Step 2: Commit** @@ -1012,7 +1039,7 @@ git add packages/core/README.md git commit -m "docs(core): add per-package README Co-Authored-By: Claude Opus 4.7 " -``` +```` --- diff --git a/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md index d8b53f15f..32dc04e3a 100644 --- a/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md +++ b/docs/superpowers/specs/2026-05-08-tier1-api-stabilization-pr2-core-design.md @@ -39,7 +39,7 @@ src/ ### `PretableGrid` interface -The current `PretableGrid extends Omit, "options">` is replaced with an explicit interface in `@pretable/core` that lists every method/property pretable promises. After rename, `GridCoreStore` becomes `PretableEngine` at the engine source — but `PretableGrid` becomes a *new, narrower* interface in `@pretable/core` that `createGrid` returns. The internal engine factory (`createGridCore`) returns `PretableEngine`; `createGrid` wraps/casts to the public `PretableGrid`. +The current `PretableGrid extends Omit, "options">` is replaced with an explicit interface in `@pretable/core` that lists every method/property pretable promises. After rename, `GridCoreStore` becomes `PretableEngine` at the engine source — but `PretableGrid` becomes a _new, narrower_ interface in `@pretable/core` that `createGrid` returns. The internal engine factory (`createGridCore`) returns `PretableEngine`; `createGrid` wraps/casts to the public `PretableGrid`. The rationale: `Omit<>` inheritance leaks the engine type into the public surface and forces every `.api.md` reader to mentally subtract a key. An explicit interface is what users will read in IDE tooltips. @@ -49,32 +49,32 @@ The rationale: `Omit<>` inheritance leaks the engine type into the public surfac In `@pretable-internal/grid-core/src/types.ts` and `create-grid-core.ts`: -| Internal (today) | After rename | Notes | -|---|---|---| -| `GridCoreCellAddress` | `PretableCellAddress` | Already aliased — absorb. | -| `GridCoreCellRange` | `PretableCellRange` | Already aliased — absorb. | -| `GridCoreColumn` | `PretableColumn` | Was `PretableCoreColumn`. React imports as `PretableBaseColumn` to disambiguate from its own `PretableColumn`. PR 3 fully resolves the naming. | -| `GridCoreFocusDirection` | `PretableFocusDirection` | Already aliased — absorb. | -| `GridCoreFocusState` | `PretableFocusState` | Already aliased — absorb. | -| `GridCoreFormatInput` | `PretableFormatInput` | Was an alias — absorb. | -| `GridCoreMoveFocusOptions` | `PretableMoveFocusOptions` | Already aliased — absorb. | -| `GridCoreOptions` | `PretableGridOptions` | Was an alias — absorb. | -| `GridCoreRow` | `PretableRow` | Was a `Record` constraint; `PretableRow` already exists in `@pretable/core/types.ts`. Unify on the public name. | -| `GridCoreRowModel` | `PretableVisibleRow` | Already aliased — absorb. | -| `GridCoreSelectionState` | `PretableSelectionState` | Already aliased — absorb. | -| `GridCoreSnapshot` | `PretableGridSnapshot` | Already aliased — absorb. | -| `GridCoreSortDirection` | `PretableSortDirection` | Already aliased — absorb. | -| `GridCoreSortState` | `PretableSortState` | Already aliased — absorb. | -| `GridCoreStore` | `PretableEngine` | Internal engine handle returned by `createGridCore`. Distinct from public `PretableGrid` (see Architecture). | -| `GridCoreTransaction` | `PretableTransaction` | Was an alias — absorb. | -| `GridCoreViewportState` | `PretableViewportState` | Already aliased — absorb. | -| `RowSelectionTriState` | `PretableRowSelectionTriState` | Already aliased — absorb. | +| Internal (today) | After rename | Notes | +| -------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `GridCoreCellAddress` | `PretableCellAddress` | Already aliased — absorb. | +| `GridCoreCellRange` | `PretableCellRange` | Already aliased — absorb. | +| `GridCoreColumn` | `PretableColumn` | Was `PretableCoreColumn`. React imports as `PretableBaseColumn` to disambiguate from its own `PretableColumn`. PR 3 fully resolves the naming. | +| `GridCoreFocusDirection` | `PretableFocusDirection` | Already aliased — absorb. | +| `GridCoreFocusState` | `PretableFocusState` | Already aliased — absorb. | +| `GridCoreFormatInput` | `PretableFormatInput` | Was an alias — absorb. | +| `GridCoreMoveFocusOptions` | `PretableMoveFocusOptions` | Already aliased — absorb. | +| `GridCoreOptions` | `PretableGridOptions` | Was an alias — absorb. | +| `GridCoreRow` | `PretableRow` | Was a `Record` constraint; `PretableRow` already exists in `@pretable/core/types.ts`. Unify on the public name. | +| `GridCoreRowModel` | `PretableVisibleRow` | Already aliased — absorb. | +| `GridCoreSelectionState` | `PretableSelectionState` | Already aliased — absorb. | +| `GridCoreSnapshot` | `PretableGridSnapshot` | Already aliased — absorb. | +| `GridCoreSortDirection` | `PretableSortDirection` | Already aliased — absorb. | +| `GridCoreSortState` | `PretableSortState` | Already aliased — absorb. | +| `GridCoreStore` | `PretableEngine` | Internal engine handle returned by `createGridCore`. Distinct from public `PretableGrid` (see Architecture). | +| `GridCoreTransaction` | `PretableTransaction` | Was an alias — absorb. | +| `GridCoreViewportState` | `PretableViewportState` | Already aliased — absorb. | +| `RowSelectionTriState` | `PretableRowSelectionTriState` | Already aliased — absorb. | In `@pretable-internal/layout-core/src/types.ts`: -| Internal (today) | After rename | Notes | -|---|---|---| -| `LayoutSpan` | `PretableRowRange` | Semantic name — it represents the visible-row index range exposed via `PretableGridSnapshot.visibleRange`. | +| Internal (today) | After rename | Notes | +| ---------------- | ------------------ | ---------------------------------------------------------------------------------------------------------- | +| `LayoutSpan` | `PretableRowRange` | Semantic name — it represents the visible-row index range exposed via `PretableGridSnapshot.visibleRange`. | `AutosizeOptions` keeps its name (already pretable-friendly). diff --git a/packages/grid-core/src/index.ts b/packages/grid-core/src/index.ts index 831e776f4..9f3c99c38 100644 --- a/packages/grid-core/src/index.ts +++ b/packages/grid-core/src/index.ts @@ -24,4 +24,7 @@ export type { PretableTransaction, PretableViewportState, } from "./types"; -export type { AutosizeOptions, PretableRowRange } from "@pretable-internal/layout-core"; +export type { + AutosizeOptions, + PretableRowRange, +} from "@pretable-internal/layout-core";