Repository navigation
fix(types): the spec-shape rule condition and BulkActionDef.visible read the named view expression slots by reference (objectui#10946) - #10977
Conversation
…e` read the named view's expression slots by reference (objectui#10946) `SpecConditionalFormattingRule.condition` was `string` alone and `BulkActionDef.visible` had no arm for the protocol's envelope (optional `source`, `ast`, `meta`), both narrower than `ObjectListViewSchema` declares and than `ObjectGrid`'s evaluator reads, so relaying a named view into a grid needed a type assertion. - `condition` is `string | <spec slot>`, the slot indexed by reference from `z.input<typeof ObjectListViewSchema>`. - `visible` is `ExpressionWire | <spec slot>`, same derivation. - The zod twin (`SpecRuleConditionSchema`) keeps `z.string()` first, so a string parses exactly as before, and reads the spec's slot schema by reference for the envelope; both rule unions (list view, kanban) use it. - `ObjectView` drops the two relay assertions the gap forced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm
… changeset (objectui#10946) - `spec-expression-wire-slots-10946.test.ts` (types): relays of the named view's own rule and bulk-def values with no assertion (tsc is the pin), the zod twin's input equal to the TS member, envelope acceptance on both rule unions with string / empty-string controls, and the spec arm's reference identity with a control that can fail. - `specExpressionWire-10946.test.tsx` (plugin-grid): the real grid paints an envelope-matched row (string control), the bulk fold reads `source` beside `ast`, and an `ast`-only envelope is a warned fault on both paths. - Changeset: `@object-ui/types` minor, breaking for readers spelled out. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm
|
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: Inputs read: card #10946 (body, triage Check-runs on the head at write time: 43, every one ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #10946
Clause-②: yes — widens two published types to the spec's expression-input wire (triage execution note 3).
What changed
SpecConditionalFormattingRule.conditionandBulkActionDef.visiblein@object-ui/typesnow read the named view's own expression slots BY REFERENCE, from the authoring (z.input) face ofObjectListViewSchema. That is the derivationObjectViewSchema.listViewsalready uses (objectui#7928). There is no hand-written copy of the spec wire.SpecConditionalFormattingRule.conditionstringstring, or the slot type ofObjectListViewSchema.conditionalFormatting[].conditionBulkActionDef.visiblestring | { dialect?: string; source: string }, spelled inlineExpressionWire(the same union, now by name), or the slot type ofObjectListViewSchema.bulkActionDefs[].visiblecondition: z.string(): the list view's rule union andKanbanConditionalFormattingRuleSchema. Both now read one module-privateSpecRuleConditionSchema. Its first arm isz.string(), so a string condition parses exactly as before: it is not canonicalized into an envelope, and''is still accepted. The spec slot alone would do both of those things to a string. Its second arm is the spec's own slot schema, taken by reference; a pin asserts reference identity. Thezod-mirror-parityledger rows name keys, not value types, and no key moved, so the ledger is untouched.BulkActionDefhas no standalone zod mirror. The list view'sbulkActionDefsis already the spec's schema by reference.ObjectViewroute 2 drops the two assertions PR fix(plugin-view): the registered object-view reads a named view's grid members (objectui#10885) #10937 added:conditionalFormatting … as ObjectGridSchema['conditionalFormatting']andbulkActionDefs … as ObjectGridSchema['bulkActionDefs']. Both relays now type-check as written.@object-ui/types: minor. It is breaking for TypeScript readers of these members, and the changeset says so.Assertions the PM listed that stay, and why (measured)
plugin-listListView: kept. The four casts areschema.conditionalFormatting as unknown[] | undefinedand the three(schema as any).bulkActionDefsreads. With all four removed,plugin-listtsc --noEmitexits 0 even against BASE-shaped types (ablation leg A[4] below). Their targets arereadonly unknown[]parameters or an untyped node literal, so this gap never forced them. They are outside this card and untouched (see Acceptance notes).plugin-gridresolveBulkActions: kept.action.visible as BulkActionDef['visible']stays becauseactionisNamedActionDef, anunknownpass-through bag. Removing the cast is red WITH the widened types (leg C: TS2322,visible?: {}), so it exists for a different reason.The two spec lines differ on these slots
condition/visibleslotast-only envelope@objectstack/spec17.4.0 (the pin)ExpressionInputSchema, wheresourceis optionalmainatdbddf02c(what the Spec Main Shape Gate compiles against)EvaluatedExpressionInputSchema, where a non-blanksourceis requiredExpressionInput, they follow whichever line is installed. They narrow with the next spec bump, with no local edit.mainSOURCE, with@objectstack/specmapped togit archive origin/main packages/spec/src. The installed 17.4.0 was absent from the program. Result: 0 errors in objectui files or pins. Of the 8 errors, 5 areReactnamespace errors from the probe's emptytypesand 3 are in spec source (missingpg-connection-stringand node types). A@ts-expect-erroron anast-only value was consumed, which confirms specmainrefuses that value on the slot.ast-only envelope the installed line admits. It is an evaluation fault. The formatting rule does not match, the bulk def qualifies no record, and the fault is warned. Both paths are pinned.Verification at
6f5bfdcb0turbo run type-check --continue, locally, overtypes,core,plugin-grid,plugin-view,plugin-list,plugin-kanban,app-shellandplugin-report. All 8 scripts ran, 0error TS, VERDICT command-exit 0.packages/types/suite plus the 37 other test files that nameconditionalFormatting,bulkActionDefs,BulkActionDefor the rule types:Test Files 306 passed (306),Tests 6765 passed (6765).spec-expression-wire-slots-10946.test.ts(types, 14 tests) andspecExpressionWire-10946.test.tsx(plugin-grid, 5 tests) are green. Their type halves are compiled by each package'stsconfig.test.json.check-control-bytes,check-new-cross-file-line-citations(0 new),check-spec-symbol-derivation,check-changeset-presence,check-changeset-fixed,check-changeset-no-major,check-changeset-claims,check-changeset-overwrite,check-pending-changeset-literals,check-type-check-coverage,check-test-path-roots,check-vi-mock-override-shape,check-phantom-dependencies,check-package-self-import,check-unreferenced-sources,check-node-esm-load --specifiers-only.check-governed-queue-guard --test: NOT GOVERNED.eslint --no-inline-config --format jsonover the 5 changed TS files. It reported 5 files, 0 errors and 95 warnings, all on untouched lines (none in the added lines or the two new files). The population is the rooteslint.config.js**/*.{ts,tsx}block, which includes all 5 files. That config enables no type-aware linting (noparserOptions.projectorprojectService), and no rule ineslint-rules/reads the filesystem. So this diff cannot move a verdict on an untouched file. The repo-widepnpm lintbelongs to CI.Reverse verification (ablations; each leg mutated with
ablation-replace.mjs, anchor hit proven on disk,@object-ui/typesrebuilt, dist marker counted)Leg A reverts all three derivations to the BASE shapes: the rule alias to
{ condition: string }, the bulk alias to{ visible?: never }, andSpecRuleConditionSchematoz.string(). It also removes the fourListViewcasts.plugin-viewtsc --noEmit: exit 2. TS2322 on the route-2 grid schema:conditionalFormatting, thencondition, is not assignable tostring. TS names only the first incompatible member.typestsc -p tsconfig.test.json: exit 2, with 7 errors, all in the new pin: the five relays, the envelope rule, and theastexcess property.plugin-gridtsc -p tsconfig.test.json: exit 2, with 2 errors in the new grid pin.plugin-listtsc --noEmitwith theListViewcasts removed: exit 0. This is the control showing those casts are not this gap's.z.string()that has no.options. The string and empty-string controls stay green.Leg B reverts only the
visiblearm.plugin-viewtsc --noEmitexits 2:bulkActionDefsis incompatible, thenvisible, thensource.Leg C keeps the widened types and removes the
resolveBulkActionscast.plugin-gridtsc --noEmitexits 2 (TS2322).Restore. Every leg was restored with
git checkout HEAD -- PATH, and each restore was checked: blob equal to the HEAD blob, andgit diff HEADempty.@object-ui/typeswas rebuilt, all 3 mutation markers counted 0 in dist, andgit status --porcelaincame back empty.The plugin-grid runtime cases characterize pre-existing behaviour, so they stay green under a type-only ablation by construction. Their type half is leg A[3].
Declared surface extension
packages/plugin-grid/src/__tests__/specExpressionWire-10946.test.tsxis a new file outside the claim's file surface. The card's "evaluates" pin needs the real grid, and@object-ui/typeshas no evaluator to import. It is a new file only; no existing file outside the claim was edited.Not measured locally (CI owns)
pnpm test(8 shards).pnpm lint.pnpm type-checkfor the packages not listed above.Acceptance notes
ListViewcasts (polish, not filed; carrier: none). The four casts are redundant, as leg A[4] measures, but for a reason outside this card. They were left untouched.@object-ui/coreFieldRulePredicate(observation, not filed). It declaressourceas required, which is narrower than the installed slot. Every call site that hands it these members already casts, and it converges with specmain's narrowing.17393ae3c. That commit carries a model-namedCo-Authored-Bytrailer. The dispatch contract asks for model-free trailers. History was not rewritten, because the branch is never force-pushed.6f5bfdcb0is model-free.Generated by Claude Code