Skip to content

build(types)!: ship the ./zod subpath as ONE bundled module (#8598) - #8646

Merged
os-warren merged 3 commits into
mainfrom
claude/issue-8598-zod-single-bundle
Sep 9, 2026
Merged

build(types)!: ship the ./zod subpath as ONE bundled module (#8598)#8646
os-warren merged 3 commits into
mainfrom
claude/issue-8598-zod-single-bundle

Conversation

@os-warren

@os-warren os-warren commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Fixes #8598.

Manifest half landed under decision batch #103 (option A). The contract review then returned FAIL on 8b8cbfd for one real defect this PR introduced, plus two owed items; all three are addressed on d7a81dbbe6ca5bc33a4c92251928cbbdc452220f.

⚠️ The defect the review caught, and where it is fixed

Test (shard 2/4) was red on 8b8cbfd on a diff that touched no test at all.

packages/cli/src/__tests__/cli-bin.test.ts self-builds @object-ui/types when the zod bundle is absent — CI's test job has no build step, by design — and it spawned pnpm --filter @object-ui/types run build with the vitest worker's entire environment. Vitest sets VITEST=true, children inherit it, all 24 packages/* vite configs open with if (process.env.VITEST) { assertCanonicalVitestInvocation(...) }, and that guard derives its vitest root from cwd — which pnpm --filter sets to the package directory. So the guard read a build as a vitest run launched from the wrong place and called process.exit(1) before the bundler started.

⭐ The build script, the spawning test and the guard are each correct in isolation. This PR created the intersection: it made @object-ui/types the first vite-built package that a test builds from inside vitest. The cli's own self-build survives only because it builds with tsup. On 8e028c2 the build script never loaded the config, so nothing could have surfaced it earlier.

Fix home chosen: the spawn, not the config

Chosen scrub VITEST from the spawned build's env (BUILD_ENV in cli-bin.test.ts, applied to both build spawns in that file — the only two in the repo)
Rejected gate the config on vite's command: 'build' instead of the variable

Three reasons, in order of force:

  1. The variable is what is false. VITEST means "vitest is loading this config". In a build the test starts, that is untrue. The spawn is the only place that knows its child is a build rather than a test run.
  2. The rejected fix is mechanically refused. scripts/__tests__/vitest-invocation-guard.test.ts requires the literal if (process.env.VITEST) { + assertCanonicalVitestInvocation( shape in every packages/* vite config. Gating on command would red that ratchet and diverge 1 of 24 byte-identical blocks.
  3. That ratchet's own case name states the property being violated"gates that call on VITEST, so vite build is never refused". The leak falsifies it from OUTSIDE, where no config can see it.

What the rejected fix would still leave open: it immunises one config and leaves the other 23 exactly as exposed — the next test that spawns a build of @object-ui/fields, plugin-grid or any of the rest breaks the same way. The chosen fix is caller-side, so it holds no matter which package a future spawn targets.

Item 4 — the class, not just the symptom

The review recorded this class LOW last round and it became the HIGH defect this round. Closed two ways:

  • scripts/__tests__/spawned-build-vitest-env-8598.test.ts (new) derives every build spawn in the test tree by AST, resolves an env: identifier to its declaration in the same file, and requires VITEST to be scrubbed. Population floor plus a named member, so an empty walk goes red rather than green.
  • zod-subpath-bundle-config-8598.test.ts's header now says that importing the config executes that same guard, why it passes there (canonical root invocation) and where the harmful face of the class was repaired.

⚠️ Worth recording: the ratchet first went red on the fixed tree — it read the env: property text, and the fix is naturally written as a named constant (env: BUILD_ENV), which contains no VITEST token. Resolving the identifier to its declaration is what makes it a measurement. A gate that reports a fixed tree as broken is one edit away from a gate that reports a broken tree as fixed.

Both legs of the re-measurement

Leg (c) is the review's prescribed shape: from the repo root, with packages/types/dist/zod/index.zod.js absent, pnpm exec vitest run packages/cli/src/__tests__/cli-bin.test.ts.

leg command before the fix (8b8cbfd) after (d7a81db)
(c) CI shape repo root, bundle absent, the real test exit 1Failed to build @object-ui/types for tests, 1 file failed exit 0 — 1 file passed, 38 tests passed
(d) control bundle present, same test exit 0, 38 passed exit 0, 38 passed
(a) minimal VITEST=true pnpm --filter @object-ui/types run build exit 1, guard refusal (vitest root: …/packages/types vs 仓库根 …/objectui-issue-8598) exit 1 — unchanged by design
(b) control same with env -u VITEST exit 0, ✓ built in 157ms, 124 files verified exit 0

⭐ Leg (a) staying red is the point: the guard is untouched and still refuses a VITEST-marked build. What changed is that no test lies to it any more. And on leg (c) after the fix, the test's own beforeAll rebuilt the artifact and it is the bundle — 0 relative specifiers — so the CLI suite now exercises the new published face.

Ratchet reverse-verification, hash-proven and trap-restored: fixed file sha256 9f633e13… with 2 scrubs → mutated to 70e38e39… with 1 → the ratchet goes red naming cli-bin.test.ts:103 → restored to 9f633e13…, 2 scrubs.

Item 5 — the changeset now carries the deep-link sentence

It was byte-unchanged in the previous increment; the statement lived only here. Added to .changeset/8598-zod-subpath-single-bundled-module.md, and re-measured rather than inherited: a raw-path sibling keeps the pre-#8344 accept set (nested off-spec ACCEPTED), the path is not reachable through the package name (ERR_PACKAGE_PATH_NOT_EXPORTED), and mixing a raw-path import with the bundled entry yields two distinct schema instances (Bundled === RawPathfalse).

⭐ Item 6 — check:published-dist is measured locally or nowhere

The ruling said CI would run it on the moved head. It cannot. published-dist-gate.yml fires only on workflow_dispatch, cron 41 3 * * *, and push: main, and its own header says why: "the gate has to build all 39 published packages. This repository deliberately has no per-PR full-repo build."

⇒ The reading below is the only one this change will ever get. ⛔ It is not deferred to CI:

pnpm check:published-dist — measured locally, exit 0. 39 published packages inspected, 5932 tarball files, 5776 of them build output, 0 tooling artifacts. Its build leg was FULL TURBO off cache entries this tree had just force-built.

⚠️ That makes it the third gate on this repo implying per-PR coverage it does not provide, after Build Docs (#8647) and check:node-esm-load.

What ships

file what it is
packages/types/package.json "build": "tsc && vite build && node ../../scripts/check-dist-completeness.mjs" + "vite": "^8.2.1"
pnpm-lock.yaml three added lines, the vite entry for this importer, nothing else
packages/types/vite.config.ts the lib-mode build of ./zod as ONE module, overwriting dist/zod/index.zod.js in place
packages/types/src/__tests__/zod-subpath-bundle-config-8598.test.ts unit pin on the config, chiefly emptyOutDir: false
packages/types/src/__tests__/zod-subpath-single-module-8598.dist.spec.tsx the built-artifact pin
packages/types/src/__tests__/package-exports-manifest.test.ts build-script expectation, edited with its demanded justification
packages/cli/src/__tests__/cli-bin.test.ts the shard-2 fix
scripts/__tests__/spawned-build-vitest-env-8598.test.ts the class ratchet
.changeset/8598-zod-subpath-single-bundled-module.md the published behaviour change, declared

The defect this card closes, in one paragraph

@object-ui/types declares "sideEffects": false. src/zod/index.zod.ts fills the #8344 node recursion point as the initializer of its AnyComponentSchema const, and tsc emitted that barrel as a module whose only other content is re-exports — so a bundler resolving import { CardSchema } from '@object-ui/types/zod' followed the re-export to dist/zod/layout.zod.js, needed nothing from the barrel's body, and the flag let it drop that body whole, fill included. Bundling removes the boundary the drop needs.

The H-check — three bundlers, each with a control

Taken on 8b8cbfd; the increment since touches no packages/types source or build input, so the artifact is unchanged (sha256 e06b8a5b…). Entry in every row: only CardSchema; zod and @objectstack/spec external. Left column is the ablation.

bundler tsc barrel (ablated) bundled ./zod
Vite 8.2.1 / rolldown 1.2.3 ACCEPTED, 18,755 / 4,835 B, fill absent REFUSED, 165,382 / 37,117 B, fill present
rollup 4.62.2 ACCEPTED, 60,002 / 18,420 B, fill absent REFUSED, 325,953 / 90,720 B, fill present
Next 16.3.1 (Turbopack) ACCEPTED REFUSED

Rollup is measured beside Vite because Vite 8 bundles with rolldown, not rollup. Well-formed control (size: 16) ACCEPTED in all six cells. Ablation hash-proven (e06b8a5b… / 0 relative specifiers / 331,934 B → 4b46cbda… / 29 / 15,943 B) and restored byte-identical under an EXIT INT TERM trap.

⚠️ Build Docs is a no-regression reading, not an accept-set one — it is green on the ablated artifact too, and per #8647 the CI check skips the build entirely on a packages/**-only diff. The Turbopack accept-set reading is the third row, from a standalone Next 16.3.1 app whose only import is CardSchema.

Lockfile — the ruling's two conditions, both MET

Mechanism: the importer block was written to the resolution already locked for 28 of the 29 existing vite importers, then verified with pnpm install --frozen-lockfile (exit 0, lockfile not rewritten, same store path as the other 28). A naive install lands 8.2.2 and drags picomatch; resolution-mode=lowest-direct gets the version right but rewrites 17/176 lines. Both measured, both rejected.

  • One version: origin/main 29 importers, this head 30, base set {8.2.1} on both. packages/types is the only addition; no existing resolution moved.
  • No unrelated line: the whole lockfile diff is 3 added, 0 removed.

The pre-existing peer-suffix split (esbuild@0.28.2 ×29, esbuild@0.27.7 ×1) and the 17 transitive vite@8.2.2 peer keys are byte-equal on both trees.

Gates on d7a81db, exit captured before any pipe

command exit verdict
pnpm --filter @object-ui/types type-check 0 all three tsc projects
pnpm --filter @object-ui/cli type-check 0
vitest run --project unit packages/types/ scripts/__tests__/ 0 Test Files 278 passed | 2 skipped (280) · Tests 6568 passed
pnpm test:dist 0 Test Files 2 passed (2) · Tests 8 passed (8)
pnpm exec eslint on the three edited/new files 0 no errors, no warnings
the four changeset gates 0 presence, no-major, fixed, overwrite
pnpm check:control-bytes 0 scanned 6840 tracked text file(s)

Carried from 8b8cbfd, unaffected by an increment that touches only tests and the changeset: pnpm check (All checks passed, CI runs it at lint.yml:481), check:published-dist (see item 6), check:node-esm-load --force-build (0, provenance 37/37 — its plain run exits 1 on a foreign shared-turbo-cache entry naming a package outside this diff, and the gate prints that remedy itself), check:dist-completeness, check:phantom-deps, check:unused-deps, check:side-effects-array, check:readme-exports, check:self-import, check:published-tsconfig-exclude, check:unreferenced-sources, check:esm-specifiers, check-governed-queue-guard --test (NOT GOVERNED).

Recorded, not fixed here

Generated by Claude Code — session session_01Jmxdo7bmeqCQHLSfmLVX9w (https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w). Kept in prose because a PR-body edit strips the markdown attribution footer.

Build the `./zod` subpath as ONE module, so the objectui#8344 node
recursion-point fill survives a bundler that honours `"sideEffects": false`.
The config overwrites `dist/zod/index.zod.js` in place, after `tsc` has
written the rest of `dist/`; no schema, no `exports` entry and no publish
contract field moves.

The manifest half — `packages/types` `build` running `vite build` between
`tsc` and the completeness count — is deliberately NOT in this commit. It is
the card's stop-and-report point and is posted on objectui#8598 for approval,
so the config here is inert until it lands. Two further files are withheld
with it because they are RED until it lands, measured rather than assumed:
the built-artifact pin for the bundled face, and the build-script expectation
in `package-exports-manifest.test.ts` that asks, by design, to be edited and
justified when a bundler step arrives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3477.4 KB 3512.7 KB
Main entry chunk (gzip) 143.9 KB 350 KB
Entry file index-CUuu9hOC.js
Status PASS

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.93KB 114.12KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 10.12KB 3.28KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 243.73KB 61.53KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 49.00KB 13.91KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.53KB 46.34KB
plugin-dashboard (index.js) 131.43KB 34.44KB
plugin-designer (index.js) 213.21KB 43.63KB
plugin-detail (index.js) 251.10KB 64.96KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.30KB 56.63KB
plugin-kanban (index.js) 55.44KB 15.73KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.33KB 3.25KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Contributor

Contract review (claude-fable-5-1, isolated seat) — PR #8646 @ 8e028c2

Verdict: CHANGES REQUIRED

Read from refs/review/8646 against merge-base c4326fe (origin/main); nothing in the PR body was taken on trust. Head is draft, 1 commit, 3 files, +236/−0: packages/types/vite.config.ts (new), packages/types/src/__tests__/zod-subpath-bundle-config-8598.test.ts (new), .changeset/8598-zod-subpath-single-bundled-module.md (new).

Card #8598 H-check: leg (a) — NOT satisfiable on this head: nothing invokes vite.config.ts, so dist/zod/index.zod.js is still tsc's barrel and a CardSchema-only entry still ACCEPTS the nested off-spec node by construction. The PR's three-bundler table (Vite/rolldown REFUSED 165,382 / 37,117 B; rollup REFUSED 325,953 / 90,720 B; Turbopack REFUSED; ablated barrel ACCEPTED in all three, controls ACCEPTED in all six) was taken on an unpushed local commit 888d6e2 — it is not reproducible from this PR, and I could not reproduce it here either (no node_modules in this checkout; stated, not hidden). The config shape is consistent with the claim: lib-mode, single es entry src/zod/index.zod.ts, everything relative inlined, so CardSchema and the nodeUnionOptions[0] = installed write (base.zod.ts:122) land in ONE module and the per-module sideEffects:false drop has no boundary to act on. That is reasoning about the config, not a measurement of this head. / leg (b) — Build Docs reports success on this head but ran 13 s and its log says No docs-related files changed. Skipping the steps below; this check still reports. (ci.yml filters on apps/site/ + content/). It built nothing. Leg (b) is therefore unmeasured by CI on this head; the PR's local 30/30 tasks successful, Next.js 16.3.1 (Turbopack) is again on 888d6e2.

Governed paths touched: NO (AGENTS.md, CLAUDE.md, .claude/**, docs/adr/**, content/docs/releases/** all absent from the diff; Governed Surface Queue Guard green). Carriers: needs:contract-review present on the PR and on card #8598.

Clause-②: the published @object-ui/types/zod face's accept set changes on partial/single-schema entries (ACCEPTED → REFUSED for a nested off-spec node) once the manifest half lands; exports, files, sideEffects, main/module/types are byte-identical. That is enforcement of the #8344 accept set arriving where it was declared, not a new accept set. Deep-link consumer class: dist/zod/layout.zod.js and siblings are KEPT (emptyOutDir: false; tsc still writes them); they load as before. FROM: one shared module graph in which a partial entry silently loses the fill. TO: the ./zod entry is one self-contained module; a raw file-path deep link (not a published entry — exports has no wildcard) still evaluates the fill-less tsc sibling and, if mixed with the bundle, is a SECOND instance of every schema. Changeset is minor, matching the seat's Clause-② = yes ruling; patch would also be defensible since exports are identical — no objection to minor.

The manifest question, plainly

packages/types/package.json is untouched on this head: "build": "tsc && node ../../scripts/check-dist-completeness.mjs" (the script line did NOT move), devDependencies = {@object-ui/test-support, typescript} (no vite), "sideEffects": false intact, exports unchanged, no pnpm-lock.yaml change. vite exists only as the root devDependency (package.json:160, ^8.2.1) and nothing on this head runs it. So this head ships a config, a unit pin on the config, and a changeset — it does not build the single module. The withheld half (build-script line, optional vite devDependency, the package-exports-manifest.test.ts pin edit, the .dist.spec.tsx artifact pin) is posted on #8598 at 5590650748 / 5590701406. Card #8598 is in needs-user-decision for exactly this; the ask, verbatim: 「你要做的:回一个字 —— AB。」— A = declare "vite": "^8.2.1" in packages/types devDependencies alongside the build-script line (matches 23/23 sibling configs; costs a vite@8.2.2 second copy in the lockfile until pnpm dedupe); B = build-script line only (measured to work; check:phantom-deps permits root-declared tooling). This PR's shape waits for that decision and does not pre-empt itvite.config.ts is identical under A and B.

Gate readings (scripts read on the head; git diff … -- scripts/ .github/ is empty — no gate literal moved)

  • check:dist-completenessbuildsWithTsc is build.split('&&')[0].trim() === 'tsc' (check-dist-completeness.mjs:146); unchanged now and still true after tsc && vite build && …. Counts presence only, so an in-place overwrite of dist/zod/index.zod.js keeps 124/124.
  • node-esm-load — reads manifest.exports['.'] (check-node-esm-load.mjs:761); ./zod is not in its path. Unaffected.
  • readme-exports — reads exports['.'] (check-readme-exports.mjs:686). Unaffected.
  • side-effects-array — arrays only; false is out of scope by design (check-side-effects-array.mjs:201-202). Skipped, as the card predicted.
  • published-dist — scans tarball dist/ for tooling material; a bundled index.zod.js is not tooling. Unaffected by reasoning; NOT run here or by the dev (stated as such in the PR).
  • turbo build inputs — $TURBO_DEFAULT$ plus root scripts/vitest-invocation-guard.mjs; a package-local vite.config.ts is already an input, so no turbo.json edit is needed when the script line lands.
  • Aliases — vitest.config.mts:501 and apps/console/vite.config.ts:464 both alias @object-ui/types/zodpackages/types/src/zod/index.zod.ts; the diff touches neither (0 lines). Console/vitest are unaffected by a dist bundle, as the card records.
  • Bundle Analysis — eager closure 3477.4 KB / 3512.7 KB; chunk framework 70.6 KB / 97.7 KB ceiling (PER_CHUNK_GZIP_CEILINGS.framework = 100_000, check-eager-closure-budget.mjs:665), headroom 27.1 KB; ceiling freshness OK. Unmoved by construction (console aliases to src, config inert).

CI on 8e028c2 (read once, 33 runs)

Type Check — FAILURE. Build Docs success (but skipped internally, see above). Bundle Analysis success. Test (shard 1/4 … 4/4) all success. README Export Check success. Lint, Build & E2E, Changeset Declaration / Bump Policy / Fixed Group / Overwrite Report, Governed Surface Queue Guard, Doc Snippet Type Check, Docs Route Eager Closure Check, Pre-Install Import Graph Check all success; Test (coverage) skipped by design. mergeable_state: behind (first read unknown). Draft.

Commit trailers on 8e028c2: Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> and Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w — both present.

Findings

  1. HIGH — Type Check is red on the head, and the PR body says it was green. @object-ui/types:type-checkvite.config.ts(14,8): error TS7016: Could not find a declaration file for module '../../scripts/vitest-invocation-guard.mjs'. Mechanism: the new unit test does import viteConfig from '../../vite.config.js', and tsconfig.test.json (include: src/**/*.test.ts, strict: true) follows that import into vite.config.ts and then into the untyped .mjs guard. The 23 sibling vite.config.ts files carry the identical import and are green only because no sibling type-check project ever includes them (packages/fields/tsconfig.json etc. include src only) — this PR is the first to pull a vite.config.ts into a checking program, which is also why the dev's own "not covered by any type-check project" observation and the type-check exit 0 row in the body cannot both be true for this file. Expectation: make the import typeable (a scripts/vitest-invocation-guard.d.mts shim, or an allowJs-free typed re-export) or stop importing the config from a tsc-checked test (e.g. load it through Vite's loadConfigFromFile in a non-tsc project); then re-run pnpm --filter @object-ui/types type-check and quote the exit code and verdict line from the PUSHED head.
  2. HIGH — this head, merged alone, ships a changeset that is false. The changeset states dist/zod/index.zod.js "is now a single self-contained module built with Vite in lib mode" and that partial entries now REFUSE; on this head none of that happens (inert config). The PR is honest about it (Part of, "inert"), but the changeset rides in the release notes the moment the head merges. Expectation: the manifest half (whichever of A/B the maintainer picks) lands in THIS PR before it leaves draft, or the changeset moves to the commit that carries the build-script line. Do not merge 8e028c2 by itself.
  3. MEDIUM — both H-check legs are unmeasured on any pushed commit. Leg (a) cannot be true on this head; leg (b)'s CI check is a 13-second skip. Every number in the PR is from local 888d6e2, which does not exist on the remote. Expectation: once the manifest half is pushed, the follow-up contract review re-measures on THAT head — the .dist.spec.tsx pin (0 relative specifiers + CardSchema REFUSES / control ACCEPTS) is the right instrument for leg (a) and CI's pnpm test:dist will collect it; for leg (b) quote a turbo run build --filter=@object-ui/site log tied to the pushed sha, and do not cite the Build Docs check for a packages/**-only diff (the seat has filed the path-filter question separately).
  4. LOW — the config's VITEST guard now fires at test-import time. Because the unit test imports vite.config.ts while process.env.VITEST is set, assertCanonicalVitestInvocation runs inside the test's module graph; a non-canonical invocation now fails as a test-file import error rather than at config load. Shards are green, so this is behavioural, not blocking. Expectation: one header sentence in the test saying so, or import only the exported default via a path that skips the guard.
  5. LOW — the deep-link FROM/TO is not in the changeset. The "Cost" paragraph names the indivisible subpath but not that a raw-path dist/zod/<category>.zod.js import is unsupported, stays fill-less, and is a second schema instance if mixed with the bundle. Expectation: one sentence in the changeset; no code change.
  6. INFO — check:published-dist not run (by the dev or here); unaffected by reasoning on an inert head. CI does not name it among the 33 runs on this head; it should be quoted on the head that carries the build-script line.

Maintainer-only merge: yes. Landing must wait for the A/B decision in the decision box on #8598 — on this head there is nothing to merge that changes published behaviour, and merging it alone would publish finding 2. After the decision: fold the chosen manifest half into this PR, fix finding 1, undraft, and request the second contract review on the new head.


Generated by Claude Code

…#8598)

Lands the manifest half the card held for the stop-and-report point, ruled
**A** by the director seat's decision batch #103. `packages/types` now builds
`tsc && vite build && node ../../scripts/check-dist-completeness.mjs`, and
declares `vite` explicitly like the other 23 packages that carry a
`vite.config.ts`. With this, `dist/zod/index.zod.js` is ONE self-contained
module and a consumer importing a single schema from `@object-ui/types/zod`
gets the same accept set as one importing the barrel: a nested off-spec node
is REFUSED where it was silently ACCEPTED.

The lockfile is settled in the same commit, per the ruling's two measurable
conditions. The importer block is pinned to the resolution already locked for
28 of the 29 existing vite importers, so the diff is exactly three added lines
and `vite` stays at ONE version across all 30 importers. A naive install was
measured first and rejected: it lands 8.2.2 beside the rest and drags an
unrelated `picomatch` / `rolldown` refresh with it.

Also lands the two pins that could not travel without this:

- `package-exports-manifest.test.ts` asks, by design, for its build-script
  expectation to be edited and justified when a bundler step arrives. The
  justification is written in: lib mode, `formats: ['es']`, ONE format, so the
  `require`-less exports map below it stays correct.
- `zod-subpath-single-module-8598.dist.spec.tsx` is the built-artifact pin —
  the shipped barrel imports no sibling category module, and `CardSchema` from
  it REFUSES the nested off-spec node while still accepting the well-formed
  control.

`zod-subpath-bundle-config-8598.test.ts` moves its config import behind a
variable specifier. A literal one pulls `vite.config.ts` into this package's
type program (`tsconfig.test.json` compiles every test, deliberately), and the
config imports the untyped `vitest-invocation-guard.mjs` — TS7016, measured on
this tree. The runtime import, and every assertion, is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
@os-warren os-warren changed the title build(types): build the ./zod subpath as ONE module (#8598) — manifest half withheld build(types)!: ship the ./zod subpath as ONE bundled module (#8598) Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3477.6 KB 3512.7 KB
Main entry chunk (gzip) 143.9 KB 350 KB
Entry file index-BkOatu4S.js
Status PASS

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 499.42KB 114.32KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 10.12KB 3.28KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 244.36KB 61.61KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 49.00KB 13.91KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.53KB 46.34KB
plugin-dashboard (index.js) 131.43KB 34.44KB
plugin-designer (index.js) 215.51KB 44.29KB
plugin-detail (index.js) 251.25KB 65.00KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.18KB 56.62KB
plugin-kanban (index.js) 55.44KB 15.73KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.33KB 3.25KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

`Test (shard 2/4)` went red on `8b8cbfd` on a diff that touched no test.
`cli-bin.test.ts` self-builds `@object-ui/types` when the zod bundle is
absent — CI's test job has no build step by design — and it spawned
`pnpm --filter @object-ui/types run build` with the vitest worker's whole
environment. Vitest sets `VITEST=true`; children inherit it; all 24
`packages/*` vite configs open with
`if (process.env.VITEST) { assertCanonicalVitestInvocation(...) }`; and that
guard derives its vitest root from `cwd`, which `pnpm --filter` sets to the
package directory. So the guard read a build as a vitest run launched from the
wrong place and exited 1 before the bundler started.

⭐ The build script, the spawning test and the guard are each correct alone.
This PR created the intersection by making `@object-ui/types` the first
vite-built package that a test builds from inside vitest; the cli's own
self-build survives only because it builds with `tsup`.

Fixed at the SPAWN — the environment is what is false there, and it is the one
place that knows the child is a build rather than a test run. ⛔ Not fixed by
gating the config on vite's `command`: that diverges 1 of 24 byte-identical
guard blocks, and `scripts/__tests__/vitest-invocation-guard.test.ts` refuses
that divergence mechanically — its own case name is "gates that call on VITEST,
so `vite build` is never refused", i.e. the property the leak falsifies from
outside, where no config can see it.

`scripts/__tests__/spawned-build-vitest-env-8598.test.ts` keeps the class shut:
it derives every build spawn in the test tree by AST, resolves an `env:`
identifier to its declaration, and requires `VITEST` to be scrubbed. Both of
today's spawns are covered; a third cannot land unguarded.

Also lands the two owed items from the review: the unit pin's header now says
that importing the config EXECUTES that same guard and why it passes here, and
the changeset gains the deep-link sentence — a raw-path sibling keeps the
pre-#8344 accept set, is not reachable through `exports`
(`ERR_PACKAGE_PATH_NOT_EXPORTED`), and mixing it with the bundled entry yields
two distinct schema instances (measured).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3477.6 KB 3512.7 KB
Main entry chunk (gzip) 143.9 KB 350 KB
Entry file index-BkOatu4S.js
Status PASS

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 499.42KB 114.32KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 10.12KB 3.28KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 244.36KB 61.61KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 49.00KB 13.91KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.53KB 46.34KB
plugin-dashboard (index.js) 131.43KB 34.44KB
plugin-designer (index.js) 215.51KB 44.29KB
plugin-detail (index.js) 251.25KB 65.00KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.18KB 56.62KB
plugin-kanban (index.js) 55.44KB 15.73KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.33KB 3.25KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ship @object-ui/types/zod as ONE bundled module so the node recursion-point fill survives sideEffects:false deep-linking bundlers

2 participants