Skip to content

Commit 9826516

Browse files
committed
feat(types)!: bind the component union in the getter, and narrow the chatbot arm
Implements decision batch #93 (objectui#8344 comment 5585333656), items F2, F3, F5 and the stale-text half of items 8/9. Changeset text is NOT yet updated in this commit; its three false "by ruling" attributions are the next push. F3 — the tree-shake leak. `base.zod.ts` now imports `AnyComponentSchema` and reads that binding INSIDE `SchemaNodeSchema`'s `z.lazy` getter. The option-array write, `defineNodeComponentUnion` and its identity assertion are gone with it. `"sideEffects": false` stays true and untouched: this module performs no load-time write at all now. Measured, not assumed — this repo's own Vite/rollup lib build, an entry importing ONLY `CardSchema`: before this commit 370,652 raw / 113,887 gzip, no fill, nested off-spec node ACCEPTED — the redirect silently inert after 1,147,266 raw / 342,193 gzip, nested off-spec node REFUSED — the union is retained because the binding is read A graph that never evaluates the barrel now throws `ReferenceError: Cannot access 'BaseSchema' before initialization` at import instead of quietly answering as `main`. That is the ruled behaviour, and its cost is paid here: 102 `packages/types` test files entered at a category module and now carry a barrel-first import. Whole unit project after the fix: 989 files, 16,837 tests, 0 failures. F2 — the chatbot widening, eliminated rather than declared. The arm the getter installs is `AnyComponentSchema.superRefine(...)`, which checks a nested `chatbot` node's `body` against `BaseSchemaCore.shape.body`. The root mirror is untouched, so a root `chatbot` with a record `body` still parses and the same node one slot down does not. Both directions pinned, plus a non-vacuity leg and a leg asserting the refusal names `body`. The discrimination objectui#8498 added survives the wrapper (`propValues` intact), so a nested refusal still costs one arm. F5 — depth on the redirected path: 276 / 3,626 / 8,404 / 14,610 / 22,244 chars at depths 0-4, all refused, none throwing. New pins cover depths 0-4 through `safeValidateSchema`, a linear-growth ceiling at depth 4, and a legal-leaf control. Items 8/9 — `any-component-union-fanout.test.ts`'s rationale said a nested document is "simply ACCEPTED"; corrected in place. The pin's identity-leg comment and header now describe THIS head. The objectui#7918 row returns to `TDZ_BOUND`: the getter builds the node union per call again, so `getter() === getter()` is FALSE, and `unstableLazyExports` reads 8 again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CZY49skxUBYyJcdnTcYPrE
1 parent 05efe7d commit 9826516

104 files changed

Lines changed: 654 additions & 205 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎packages/types/src/__tests__/accordion-item-authorable-keys.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
* so re-adding `icon?` to the interface fails the build on the unused directive.
4848
*/
4949

50+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
51+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
52+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
53+
import '../zod/index.zod.js';
5054
import { describe, it, expect } from 'vitest';
5155
import type { AccordionItem } from '../disclosure';
5256
import { AccordionItemSchema } from '../zod/disclosure.zod';

‎packages/types/src/__tests__/action-callback-retired-7068.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
* assertions are erased before it runs.
5252
*/
5353

54+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
55+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
56+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
57+
import '../zod/index.zod.js';
5458
import { readFileSync, readdirSync, statSync } from 'node:fs';
5559
import { join, relative, resolve } from 'node:path';
5660
import { describe, it, expect } from 'vitest';

‎packages/types/src/__tests__/alert-dialog-read-dialect-7104.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
* renderer and that one cannot see the mirror's shape.
7070
*/
7171

72+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
73+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
74+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
75+
import '../zod/index.zod.js';
7276
import { describe, expect, it } from 'vitest';
7377
import { readFileSync } from 'node:fs';
7478
import { dirname, join } from 'node:path';

‎packages/types/src/__tests__/any-component-union-fanout.test.ts‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,24 @@
2828
* refused node 4 deep 19,311 -> 4,330 chars
2929
*
3030
* A bound that also passed on the flat union would assert nothing, which is the
31-
* failure mode this card is most exposed to: `AnyComponentSchema` does not yet
32-
* recurse into child slots (objectui#7869 / objectui#8344), so a nested document
33-
* is simply ACCEPTED and a naive "does not throw at depth 4" test is green for
34-
* the wrong reason. The depth case below is therefore built on `MenuItemSchema`,
35-
* which ALREADY refuses at depth on this tree.
31+
* failure mode this card was most exposed to. ⚠️ The reason it was exposed has
32+
* since changed and this paragraph is corrected in place rather than deleted:
33+
* when this file was written `AnyComponentSchema` did not recurse into child
34+
* slots, so a nested document was simply ACCEPTED and a naive "does not throw at
35+
* depth 4" test was green for the wrong reason — which is why the depth case
36+
* below is built on `MenuItemSchema`, one of the few schemas that ALREADY refused
37+
* at depth on that tree. objectui#8344 has since redirected the node recursion
38+
* point, so a nested off-spec node IS refused now and the `MenuItemSchema` choice
39+
* is no longer load-bearing. ⛔ It stays anyway: it is the case this card measured
40+
* and re-pointing it would retire the measurement without replacing it. The
41+
* redirected path gets its own depth pin in
42+
* `node-recursion-point-8344.test.ts`, where the linear-growth reading lives.
3643
*/
3744

45+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
46+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
47+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
48+
import '../zod/index.zod.js';
3849
import { describe, it, expect } from 'vitest';
3950
import { z } from 'zod';
4051
import { AnyComponentSchema, safeValidateSchema } from '../zod/index.zod.js';

‎packages/types/src/__tests__/app-action-onclick-refusal-6854.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* the clause whose truth this card measured.
3737
*/
3838

39+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
40+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
41+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
42+
import '../zod/index.zod.js';
3943
import { describe, it, expect } from 'vitest';
4044
import { AppActionSchema, MenuItemSchema } from '../zod/app.zod';
4145

‎packages/types/src/__tests__/app-hidden-catalogue-flag-7542.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
* this node would have read as "not hidden" without a sound.
7171
*/
7272

73+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
74+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
75+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
76+
import '../zod/index.zod.js';
7377
import { describe, it, expect } from 'vitest';
7478
import { readFileSync } from 'node:fs';
7579
import { dirname, join } from 'node:path';

‎packages/types/src/__tests__/base-bind-declared.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
* before this declaration existed, via the index signature and `.passthrough()`.
9191
*/
9292

93+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
94+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
95+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
96+
import '../zod/index.zod.js';
9397
import { describe, it, expect } from 'vitest';
9498
import { readFileSync } from 'node:fs';
9599
import { fileURLToPath } from 'node:url';

‎packages/types/src/__tests__/base-schema-hidden-predicate.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@
7676
* why this was ruled rather than applied mechanically.
7777
*/
7878

79+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
80+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
81+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
82+
import '../zod/index.zod.js';
7983
import { describe, it, expect } from 'vitest';
8084
import type { BaseSchema } from '../base';
8185
import { BaseSchema as Mirror } from '../zod/base.zod';

‎packages/types/src/__tests__/base-schema-predicate-envelope-7530.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@
7979
* object arm of `boolean | string` does not exist.
8080
*/
8181

82+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
83+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
84+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
85+
import '../zod/index.zod.js';
8286
import { describe, it, expect } from 'vitest';
8387
import type { z } from 'zod';
8488
import type { BaseSchema } from '../base';

‎packages/types/src/__tests__/base-schema-zod-mirror-parity.test.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
* five keys were demonstrably narrow.
5959
*/
6060

61+
// objectui#8344: the `./zod` barrel must be the FIRST zod module this graph evaluates.
62+
// `base.zod.ts` reads `AnyComponentSchema` as an import binding, so entering at a
63+
// category module puts `BaseSchema` in its temporal dead zone and throws at load.
64+
import '../zod/index.zod.js';
6165
import { describe, it, expect } from 'vitest';
6266
import { BaseSchema as Mirror } from '../zod/base.zod.js';
6367

0 commit comments

Comments
 (0)