Repository navigation
fix(plugin-charts)!: ObjectChartBlock declares its pre-gate props instead of (props: any) - #10573
Conversation
…ead of `(props: any)`
The registry shell around ObjectChart was published as `(props: any)`, so a
misspelled prop, a string schema or a node without `type` all compiled.
Its props are now `Omit<ObjectChartProps, 'schema'> & { schema: BaseSchema }`,
built from existing exported names only. `schema` is BaseSchema, the node
SchemaRenderer hands every registered renderer, because the shell receives
the node before ElementDataSourceGate maps its binding. It is deliberately
not the post-gate ObjectChartSchema, which is also false for the `chart`
alias this same shell is registered under.
The one loose member is the hand-off into ObjectChart
(`bound as ObjectChartSchema`): that is where the pre-gate node becomes the
component's post-gate schema.
Pinned at compile time by ObjectChartBlock.props-8885.test.tsx: an
any-guard, @ts-expect-error on a misspelled prop name, a missing schema, a
string schema and a type-less node, and controls for the `chart` alias node
and a binding-only node.
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
Co-authored-by: Claude <noreply@anthropic.com>
…narrowing Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
|
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 judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
(props: any)(props: any)
Fixes #8885
Clause-②: yes — a published component signature narrows from
any(ruling 5810232641).Part 2 of objectui#8885. Part 1 landed as PR #8895.
ObjectChartBlock, the registry shell that wrapsObjectChartbehindElementDataSourceGate, now declares its props. Before, it was published as(props: any).Notation: GitHub strips angle-bracket fragments from PR bodies, so generics are spelled in words below.
Omit OF ObjectChartProps MINUS 'schema'means the TypeScriptOmitofObjectChartPropswith its'schema'key removed.What changed
ObjectChartBlock's parameter is nowOmit OF ObjectChartProps MINUS 'schema', intersected with{ schema: BaseSchema }. Both parts are existing exported names, and no new type is minted.schemaisBaseSchema, the nodeSchemaRendererhands every registered renderer (the object arm ofSchemaRendererProps.schema).dataSource,onSegmentClick) isObjectChart's own, so the type is closed.schema={bound as ObjectChartSchema}intoObjectChart. That line is where the pre-gate node becomes the component's post-gate schema. The gate maps thedataSourcebinding but does not validate, so the post-gate claim is made there, at one line, and not on the published signature.Property 'chartType' is missing in type 'BaseSchema' but required in type 'ObjectChartSchema'.object-chartand under thechartalias.ObjectChartSchema'stype: 'object-chart'literal would be false for the alias.BaseSchema'stype: stringis correct for both.packages/plugin-charts/src/__tests__/ObjectChartBlock.props-8885.test.tsx. It is compiled bytsc -p tsconfig.test.json, and--listFilesconfirms it is in that program.'@object-ui/plugin-charts': minor, with a BREAKING section written in migration terms. Published 17.6.0 shipsObjectChartBlock: (props: any) => React.JSX.Element.Why
BaseSchema(the seat's reading)The ruling types the shell's
schemaas "the registry renderer's raw node input", and it stops only "if no shared pre-gate node type exists to name".BaseSchemais exported, and it is exactly whatSchemaRendererpasses every registered renderer asschema, so naming it invents nothing. The dispatch order had added a stricter stop, "if the shells disagree", and the first round of this claim stopped on it. The measured reading was 15 of 17elementDataSourceBlockshells declaringany, 1 declaring a component-specific shape and 1 declaring a post-gate schema. That stricter condition was the dispatching seat's, not the ruling's, and the seat lifted it, choosing option A of theneeds_decisionreport on the card.Evidence (final HEAD
5fb961c13)Consumer cost, measured before writing with the objectui#7483 comment 5647422745 method. Only plugin-charts'
distwas re-emitted, and each type-check leg ran separately. Re-run at5fb961c13against the headdist:error TStsc --noEmit/tsc -p tsconfig.test.jsonnext typegen)No dependant references
ObjectChartBlockby name. Both registrations go throughComponentRegistry, which isRegistry OF any, andregisterLazyloaders are typed() => Promise OF unknown. The builtdist/index.jsis byte-identical to the base build (cmpexit 0). The onlydistchange isObjectChart.d.ts: theObjectChartBlockdeclaration and its docblock, plus theBaseSchematype import.Red on base, green on head. For the red leg, the pin file stayed at HEAD while
ObjectChart.tsxwas set back to its base blob (6ad6d4e1to1f26145d, proven by hash). Thentsc -p tsconfig.test.jsonexited 2 with 8 errors:assertionShellParamIsNotAny,assertionShellSchemaIsNotAny,assertionSchemaIsTheRawNodeandassertionRestIsObjectChartProps;@ts-expect-error) on P1 (misspelled prop namedataSorce), P2 (schem), P3 (stringschema) and P4 (node withouttype).Controls C1 (the
chartalias node), C2 (a binding-only node{ type, dataSource: { object, view } }) and C3 (ObjectChart's own props passed through) compiled on both sides. It was restored withgit checkout HEAD --and proven by blob6ad6d4e1== HEAD and an emptygit diff HEAD. On head,pnpm run type-checkfor plugin-charts runstsc --noEmit && tsc -p tsconfig.test.jsonand exits 0.Closedness ablation. Adding
[key: string]: anyto the props type throughablation-replace.mjsreds exactlyassertionRestIsObjectChartProps(TS2344) and P1 (TS2578). The any-guards and P2 to P4 stay green, so P1 catches an open props bag, not onlyany. Output:ok mutation landed: anchor 1 -> 0andok restored: blob == HEAD (6ad6d4e17f77).Tests.
pnpm exec vitest run --maxWorkers=2 packages/plugin-charts/plus threepackages/typescensus tests that readObjectChart.tsxas text (object-chart-undeclared-keys-8885,widget-schema-anchors-7946,base-bind-declared) gaveTest Files 77 passed (77)andTests 874 passed (874). That is 74 plugin-charts test files plus the 3 census files, so every file ran.Lint. eslint on the 2 touched source files, with
--no-inline-config --format json, reported 0 errors.ObjectChart.tsxhas 41 warnings against 42 on base: one fewerno-explicit-any, because the(props: any)is gone. The pin file has 1 warning, the deliberateanyinassertionAnyProbeCanFire, which proves the any-probe can fire. Repo-widepnpm lintbelongs to CI.Gates (unlocked, exit captured before any pipe):
check-changeset-presenceexit 0: "3 file(s) changed, 2 of them published source of a package the release covers".check-changeset-no-majorexit 0.check-changeset-fixedexit 0.check:changeset-claimsexit 0 (report-only).check:pending-changeset-literalsexit 0.check:new-line-citationsexit 0: "VERDICT new-cross-file-line-citations: 0 new citation(s)".check:control-bytesexit 0.check:element-data-source-declarationexit 0: "all reach the seam and take it from core".check:unreferenced-sources,check:test-path-roots,check-type-check-coverage,check:spec-symbols,check:doc-fencesandcheck:shell-escape-residue: each exit 0.check-governed-queue-guard --teston the 3 paths: NOT GOVERNED.check:readme-exportsexit 1 is PREREQUISITE NOT MET: 417 self-imports unjudgeable because their packages'distis not built. None is in plugin-charts, and no README or doc mentionsObjectChartBlock, so this diff does not reach it. NOT MEASURED, not red.Acceptance notes
Noted, not filed:
any. Read at base3261e6479: 15 of the 17elementDataSourceBlockshells publishschema: any, and two of them (object-map and object-timeline) publish a bareReact.FC OF any. This PR types onlyObjectChartBlock. A family-wide pre-gate type was option C of the decision, and it was not taken. Carrier: none.@object-ui/reactREADME types the shellFC OF { schema: BaseSchema }, as this PR now does. TheelementDataSourceBlockdoc comment besideElementDataSourceGateshowselementDataSourceBlock OF React.FC OF any. Carrier: the next edit to that file.objectNme) still compiles, throughBaseSchema's passthrough index signature. That is protocol-level, not this card's; the pin keeps a counter-probe so the ceiling stays visible.Generated by Claude Code