Repository navigation
feat(types)!: retire sixteen NamedListView members as ?: never tombstones (objectui#7924) - #10285
Conversation
…stones (objectui#7924) Bucket 2 A and bucket 3 of the director-seat ruling on objectui#7924. - The eight legacy `show*` spellings become tombstones whose docblocks name the canonical `userActions.X` / `appearance.showDescription` key. Both blocks were already declared (objectui#8980), so that step of the ruling is a no-op. - Eight protocol-silent, unread members retire the same way. - `allowExport` and `densityMode` are NOT retired: each is read (ListView's export gate; the runtime density fold onto `rowHeight`). - The runtime fold in normalize-list-view.ts is untouched. - Census pin gains an AST-derived tombstone partition, per-member compile-time refusals and protocol-shaped accepts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01877XiBYSaRCk2CU7cMSg3S
…ed-list-view-retire
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsChecked in a detached worktree at this head:
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
CI blocker, not this PR's:
Generated by Claude Code |
… navigation item type objectstack#19789 widened the spec's navigation item union with `doc`, and `NAV_TYPE_META` is a Record keyed by that spec-derived union, so objectui stopped compiling against @objectstack/spec built from objectstack main (the Spec Main Shape Gate, TS2741 on NavigationDesigner). - `doc` entry: `appDesigner.navTypeDoc`, `bg-blue-100 text-blue-700`, `BookOpen`. - The map is typed `Record<NavigationItemType | 'doc', ...>`: the pinned spec 17.4.0 has no `doc`, so a plain `doc:` key is an excess property there. The `| 'doc'` goes at the pin bump that ships `doc`. - `appDesigner.navTypeDoc` fallback in useDesignerTranslation and all ten locale packs. - Guard test: every discriminant of the installed spec's NavigationItemSchema renders a row with a resolved type badge (spec subset of map, not equality). - `doc` is deliberately NOT in QUICK_ADD_TYPES: an empty doc item fails the spec's book-or-doc requirement; authoring it is objectui#10188. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC (cherry picked from commit 6f970da)
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Part of #7924
Clause-②: yes (the declared surface grows by two protocol blocks, then narrows by eighteen tombstones; an isolated at-tier contract review happens before enqueue)
Executes buckets ② A and ③ of the director-seat ruling on objectui#7924 (issuecomment-5690906005). This PR does not do bucket ① (having the
object-viewdelegation read the 23 protocol-declared members off the named view), so the card stays open.What changed
packages/types/src/objectql.ts,NamedListView: sixteen?: nevertombstones. Each docblock carries@deprecated RETIRED (objectui#7924)and names the key to write instead.showSearch,showSort,showFilters,showHideFields,showGroup,showColorandshowDensitypoint atuserActions.search,.sort,.filter,.hideFields,.group,.rowColorand.rowHeight.showDescriptionpoints atappearance.showDescription.addDeleteRecordsInline,addRecordViaForm,clickIntoRecordDetails,collapseAllByDefault,color,fieldTextColor,prefixField,wrapHeaders.packages/core/src/utils/normalize-list-view.tsis untouched. Stored documents keep parsing and keep being folded. Only the authoring face changed.packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts:neverkeyword) and each member's docblock.block.key.undefined, plus sixteen@ts-expect-errorliterals, one for each tombstone.userActions/appearancevalues are accepted on a literal and also parse against the protocol's ownObjectListViewSchemaslots. A legacy spelling as control does not parse.p1-spec-alignment.test.ts: the only TS authoring site of the retired keys in the repo. It is migrated touserActions/rowColor.content/docs/plugins/plugin-view.mdx: theNamedListViewrow now says where the toggles live..changeset/7924-named-list-view-retire.md:minoron@object-ui/types, with the BREAKING banner and the ADR-0087 disposition line. ⛔ Notmajor.What moved from the dispatch (reported, not smoothed)
NamedListViewalready declaresuserActions?: ListViewSchema['userActions']andappearance?: ListViewSchema['appearance']. They are spec-derived by indexed access and landed with objectui#8980. Nothing was added.allowExporthas this relay line in app-shell's object page:allowExport: viewDef.allowExport ?? listSchema.allowExport,. There,viewDefis the active view resolved fromobjectDef.listViews, which app-shell's ownViewConfigPanel/view-config-adapterheaders call a flatNamedListView.ListViewthen gates export onschema.allowExport !== false &&.densityModeis relayed the same way (densityMode: viewDef.densityMode ?? listSchema.densityMode,).normalizeListViewSchemathen folds it onto top-levelrowHeight(const legacyDensity = s.densityMode;). So it is a legacy spelling with a runtime fold, the bucket-② shape. Its canonical key is top-levelrowHeight, ⛔ notuserActions.rowHeight, which is a boolean toolbar toggle.prefixFieldin exactly the same way, and nothing downstream reads it.ListViewhas zeroprefixFieldhits against non-zeroallowExporthits on the same query. That difference is whyprefixFieldwas tombstoned.colorto point atuserActions.rowColor. It points at the top-levelrowColor: { field }configuration instead, and warns offuserActions.rowColor. The reason:colornames a FIELD, anduserActions.rowColoris a boolean panel toggle. App-shell's own relay comment draws the same line.addRecordViaFormpoints at the protocol'suserActions.addRecordForm("Add records through a form instead of inline"). Both are text only.Figures, and the instrument for each
labelonly. Measured by a TypeScript AST walk: the census pin, plus a language-service script over the root tsconfig. The count does not move, because a tombstone is still a declared member. That is what makes the refusal work by name.findReferenceson each member's declaration, over the 4858 files in the root tsconfig. It found hits in one file only,p1-spec-alignment.test.ts, forshowSearch/showSort/showFilters/color. Control:columnsreturned 6 references in plugin-view.any): an AST name scan overpackages/*/src,appsandexamples(4799 files). It covered property access, element access, object-literal keys, destructuring and declarations. Absent controlzzqNoSuchreturned 0. This scan found theapp-shellrelay and the two live downstream reads.Consumer fixes
None needed. After rebuilding the closure,
tscon plugin-view, app-shell, plugin-dashboard and plugin-grid (the four packages that type againstObjectViewSchema/NamedListView) is green with zero edits. That matches thefindReferencesreading. The Studio literal carryingaddDeleteRecordsInline: trueis alist-viewschema castas never, not aNamedListView, and is untouched. Legacy stored data read through loose types (activeView?.showSearchin app-shell) is untouched by design.Verification, at
360a4fc9a(after mergingorigin/main06b82b8c3)pnpm --filter @object-ui/types type-check: all threetscinvocations echoed, includingtsconfig.test.json, exit 0.pnpm exec vitest run packages/types/:Test Files 214 passed (214),Tests 4941 passed (4941).turbo run build --concurrency=2with the four^...filters gave28 successful, 28 total. The rebuiltdist/objectql.d.tscarriesshowSearch?: never;. Thentype-checkon the four consumers: all fourDone, exit 0.eslint --no-inline-config --format jsonon the three changed TS files: 3 files, 0 errors, 34 warnings. The warnings are pre-existingno-explicit-any, andorigin/main'sobjectql.tsreads the same 34.eslint.config.jsenables no type-aware linting, so this diff cannot move a verdict on any untouched file. The repo-widepnpm lintis CI's.check-changeset-presence0,check-changeset-no-major0,check:spec-symbols0,check:new-line-citations0 (0 new citations),check:control-bytes0, andcheck-governed-queue-guard --testover the five paths reports NOT GOVERNED.showSearch?: never;was replaced byshowSearch?: boolean;throughablation-replace.mjs. Proof it landed: anchor count went 1 to 0, and blobf836ad51becameb310c292.tsc -p tsconfig.test.jsonexited 2 with exactly two errors. One is TS2344 on the every-tombstone-is-undefinedpin. The other is TS2578, an unused@ts-expect-error, on theshowSearchrefusal literal.2 failed | 227 passed. The two failures are the tombstone-set pin and theshowSearchcanonical-key pin.git checkout HEAD --. The blob is back tof836ad51= HEAD, andgit diff HEADis empty.Not run locally, declared to CI: the full
pnpm test, the repo-widepnpm lint, and vitest for the consumer packages. No runtime file changed, so their runtime tests measure nothing this PR moved.Acceptance notes
object-viewrenderer's reads offschema.listViews. App-shell's object page also holds a named view, as its active view, and relays many bucket-① members off it intolist-view. Anyone doing bucket ① should re-measure against both hosts, not only plugin-view.userActions.editInlinesits besideaddRecordFormin the protocol. Nothing here mapsaddDeleteRecordsInlineto it, because the semantics differ (inline editing, as opposed to inline add and delete).Generated by Claude Code