diff --git a/.changeset/vacuous-dts-justification-5673.md b/.changeset/vacuous-dts-justification-5673.md new file mode 100644 index 000000000..37fe29375 --- /dev/null +++ b/.changeset/vacuous-dts-justification-5673.md @@ -0,0 +1,40 @@ +--- +'@object-ui/core': patch +--- + +Withdraw the entry-surface justification on core's `SchemaNode` re-export, and put +the gauge that can actually fail in its place (objectui#5673). + +`packages/core/src/types/index.ts` carried, as the justification for the #4580 +re-export convergence, *core's own entry surface is unchanged (`dist/index.d.ts` is +byte-identical across the change — measured, both rounds)*. The reading was real and +it certified nothing. `core/dist/index.d.ts` is emitted from a barrel that only +FORWARDS the symbol, and forwarding never restates a shape — not `export *`, and not +the `export type { … }` line that names this one. Only the module that DECLARES the +symbol can move, so that file is byte-identical under any change to a re-exported +declaration's shape, and it could not have failed for the change class it was quoted +against. + +Measured for this change rather than argued. One optional key was injected into +`BaseSchema` — the shape `SchemaNode` publishes — both packages were rebuilt from a +cleared `dist/` and a cleared `tsconfig.tsbuildinfo`, then the probe was dropped and +both rebuilt again: + +| emitted file | base | with probe | probe dropped | +|---|---|---|---| +| `@object-ui/types` `dist/base.d.ts` — declares the shape | `31b5a01d…` | `8487500e…` **moved** | `31b5a01d…` | +| `@object-ui/core` `dist/types/index.d.ts` — forwards it | `0e64c8c6…` | `0e64c8c6…` | `0e64c8c6…` | +| `@object-ui/core` `dist/index.d.ts` — entry barrel, names it | `5cca207a…` | `5cca207a…` | `5cca207a…` | + +The corrected block states that calibration as a recipe with its failure mode, so the +next reader inherits a gauge that can be checked instead of a sentence that cannot. +The `ComponentRendererProps` block below it already reached the right verdict, but +gave a narrower reason for it — that core's entry is an `export *` barrel — which is +not the mechanism, and is wrong for a symbol the barrel names on its +`export type { … }` line; it now states the forwarding rule. + +Documentation only, in a published declaration file: these docblocks sit on export +specifiers, so `core/dist/types/index.d.ts` carries them into the tarball, while +`core/dist/index.d.ts` does not move for them either — the same insensitivity, +demonstrated once more on this very change. No type moves and no runtime behaviour +changes. diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index dfa836373..0a10dfe24 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -31,8 +31,46 @@ * rather than restated, so there is exactly one declaration left to disagree * with — a structural copy would reproduce the defect the moment either side * moved. This package already depends on `@object-ui/types`, so the edge exists - * and adds no cycle, and core's own entry surface is unchanged (`dist/index.d.ts` - * is byte-identical across the change — measured, both rounds). + * and adds no cycle. + * + * ## The entry-surface sentence that used to close this block is WITHDRAWN + * + * It read: *core's own entry surface is unchanged (`dist/index.d.ts` is + * byte-identical across the change — measured, both rounds)*. The reading was + * real, and it certified nothing (objectui#5673). + * + * `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this + * symbol, and forwarding never restates a shape — not `export *`, and not the + * `export type { SchemaNode, … } from './types/index.js'` line that names it. + * Only the module that DECLARES the symbol can move. So that file is + * byte-identical under any change to a re-exported declaration's shape, naming + * the symbol or not, and a gauge that cannot fail for the change class it is + * quoted against has discharged nothing. + * + * ## The gauge that can fail — and how to prove it can, before believing it + * + * 1. Watch the emitted `.d.ts` of the module that DECLARES the symbol. For + * `SchemaNode` that is `@object-ui/types`' `dist/base.d.ts`, in another + * package — not core's entry, and not core's own `dist/types/index.d.ts` + * either, which forwards exactly as the entry does. For the shape claim + * itself, resolve the symbol through the TypeScript CHECKER from + * `core/dist/index.d.ts`. + * 2. Build both legs from a cleared `dist/` AND a cleared + * `tsconfig.tsbuildinfo` — the build info lives outside `dist/`, so + * composite `tsc` skips emit if it survives and two stale trees compare + * equal for free. + * 3. CALIBRATE: inject a probe key into the declaring module, rebuild, and + * require the hash you are watching to MOVE; drop the probe, rebuild, and + * require it to come back to its original value. A probe that leaves your + * hash unmoved means the gauge is not wired to this symbol — that is what + * failure looks like here, and no "byte-identical" sentence may be written + * from a gauge that just failed it. + * + * Run against this file's own claim — probe: one additive optional key on + * `BaseSchema`, the shape `SchemaNode` publishes — `@object-ui/types`' + * `dist/base.d.ts` moved and came back, while `core/dist/index.d.ts` and + * `core/dist/types/index.d.ts` held one hash across all three legs. The + * withdrawn sentence was watching the two files that cannot move. * * The collision is only observable from a package that resolves BOTH through * `node_modules`; the pin therefore lives in `@object-ui/react` @@ -66,10 +104,12 @@ export type { SchemaNode } from '@object-ui/types'; * ## What the re-export moves, and how that was measured * * It is NOT surface-neutral, and the gauge that would have said so is vacuous. - * `core/src/index.ts` is a 95-line `export *` barrel; `core/dist/index.d.ts` is - * therefore byte-identical under ANY change to a re-exported module and cannot - * fail for this change class (objectui#5673 — which is also why the sentence - * above `SchemaNode` citing that byte-identity is not repeated here). + * `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this + * symbol — its `export type { … }` line names it, and naming is not restating + * — so that file is byte-identical under ANY change to a re-exported + * declaration's shape and cannot fail for this change class (objectui#5673, + * where the `SchemaNode` block above withdraws the same reading and carries the + * probe calibration that tells a live gauge from this one). * * Measured instead by resolving the symbol through the TypeScript CHECKER from * `core/dist/index.d.ts`, over a `dist/` + `tsconfig.tsbuildinfo` clean rebuild