Skip to content

docs(core,react): the two @examples teaching getDataConfig read the shared record source (objectui#7798) - #7809

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-7798-getdataconfig-doc-example
Sep 5, 2026
Merged

os-sam merged 1 commit into
mainfrom
claude/issue-7798-getdataconfig-doc-example

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #7798

Two doc blocks prescribed, in a copyable @example, a line that no reader outside two
plugin files can write:

const dataConfig = useMemo(() => getDataConfig(schema), [schema]);

getDataConfig is exported by nothing. It survives only as a file-local wrapper in
packages/plugin-map/src/ObjectMap.tsx:135 and packages/plugin-grid/src/ObjectGrid.tsx:444,
so outside those two files there is no module to import it from — the prescribed line does
not compile for any new caller.

Both examples now spell dataConfig the way the live call sites spell it, which is the
judgement PR #7797 applied to navigation-overlay.tsx: follow the live call sites, not
another doc block.

One measurement that strengthens the card's premise

The card recorded plugin-map / plugin-grid as surviving hand-copies and left open
whether they are "deliberate residue or a missed leg". Measured on this tree, they are
neither: both already delegate their ladder to resolveRecordSourceConfig —
ObjectMap.tsx:174 and ObjectGrid.tsx:453 both end in return resolveRecordSourceConfig(schema);,
keeping only the array-shorthand head above the shared call. So all live sites obtain this
value through the one shared producer; two of them merely wrap it under a local name. That
makes resolveRecordSourceConfig unambiguously the spelling the examples should teach, and
it is a reading, not an assumption. It does not change the card's defect: the name
getDataConfig is still exported by nothing.

⛔ Neither wrapper is touched by this PR.


The diffs — comment lines only

diff --git a/packages/core/src/utils/record-source.ts b/packages/core/src/utils/record-source.ts
@@ -68,7 +68,7 @@
  *
  * @example
  * ```ts
- * const dataConfig = useMemo(() => getDataConfig(schema), [schema]);
+ * const dataConfig = useMemo(() => resolveRecordSourceConfig(schema), [schema]);
  * const objectName = resolveRecordSourceObjectName(schema, dataConfig);
  * ```
  */
diff --git a/packages/react/src/hooks/useNavigationOverlay.ts b/packages/react/src/hooks/useNavigationOverlay.ts
@@ -210,7 +210,12 @@
  *
  * @example
  * ```tsx
- * const dataConfig = useMemo(() => getDataConfig(schema), [schema]);
+ * import {
+ *   resolveRecordSourceConfig,
+ *   resolveRecordSourceObjectName,
+ * } from '@object-ui/core';
+ *
+ * const dataConfig = useMemo(() => resolveRecordSourceConfig(schema), [schema]);
  * const { handleClick, isOpen, selectedRecord, mode, close, width } =
  *   useNavigationOverlay({
  *     navigation: schema.navigation,

record-source.ts needs no import line — the file is @object-ui/core, and its example
is now byte-identical to the resolveRecordSourceConfig example seventy lines below it in
the same file. useNavigationOverlay.ts names the import, matching PR #7797's shape, so the
line it teaches is copyable as written. The surrounding prose already carries the rule and
is left to carry it, rather than being restated.

File count: 3 changed, read from the recorded base a617bb8d3 (git diff --stat BASE),
not a two-dot origin/main..HEAD range.

Comment-only, proven two independent ways

① Every added/removed diff line matches a comment prefix. All 9 changed lines of the
-U0 diff match ^[+-] \*(\s|$) — a JSDoc continuation line. Non-comment changed lines: 0.

changed diff lines: 9
OK   '- * const dataConfig = useMemo(() => getDataConfig(schema), [schema]);'
OK   '+ * const dataConfig = useMemo(() => resolveRecordSourceConfig(schema), [schema]);'
OK   '- * const dataConfig = useMemo(() => getDataConfig(schema), [schema]);'
OK   '+ * import {'
OK   '+ *   resolveRecordSourceConfig,'
OK   '+ *   resolveRecordSourceObjectName,'
OK   "+ * } from '@object-ui/core';"
OK   '+ *'
OK   '+ * const dataConfig = useMemo(() => resolveRecordSourceConfig(schema), [schema]);'

non-comment changed lines: 0

② Both revisions transpile to byte-identical output under the repo's own TypeScript at
removeComments: true, while the raw text differs. The "after" side is read from the
working tree, not the index — a first run of this instrument read git show :FILE, which
returned the unstaged index copy (identical to the base blob) and reported a false "raw text
does not differ"; that read was fixed before the numbers below were taken.

repo TypeScript version: 6.0.3
typescript resolved at : node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/typescript.js
base revision         : a617bb8d3eff9aaa22a12283426430c1e942c134

packages/core/src/utils/record-source.ts
  raw text     before/after sha256: 86bba64a6a37a704 / 31b09cf9ecba496b  -> DIFFERS: true
  emitted (removeComments:true)    : 3b5ae65d32f4314c / 3b5ae65d32f4314c  -> BYTE-IDENTICAL: true
  emitted byte length              : 551 / 551

packages/react/src/hooks/useNavigationOverlay.ts
  raw text     before/after sha256: 39d4bc651987d7a2 / 64a435aa4c47ef27  -> DIFFERS: true
  emitted (removeComments:true)    : c281f34e765bdb5e / c281f34e765bdb5e  -> BYTE-IDENTICAL: true
  emitted byte length              : 3285 / 3285

VERDICT: COMMENT-ONLY (raw text differs, emitted bytes identical) for all files

⇒ The Clause-② void condition (any change to an executable line under packages/*/src) is
not met.

Type-check readings — through turbo

type-check dependsOn ^build, so it is run through turbo, not as a bare package script.

command tasks exit
turbo run type-check --filter=@object-ui/core --concurrency=2 3 successful, 3 total (1 cached) 0
turbo run type-check --filter=@object-ui/react --concurrency=2 6 successful, 6 total (1 cached) 0

⚠️ An unmet prerequisite, reported as such and not as a result. The first attempt used
pnpm --filter @object-ui/core type-check, which runs the package script directly and
bypasses turbo's ^build. It produced ~20 TS6305 ("Output file packages/types/dist/index.d.ts
has not been built from source file") plus two cascading TS7006/TS2322. That is the
dependency declarations not having been built — not a type error in this change. Through
turbo, which builds them first, both packages are clean.

check:doc-example-readers re-check — still green, ledger still empty

OK  80 documented symbol(s), 3944 call site(s), 11 slot(s) where a call site delegates to a shared reader — no @example hand-spells one.

exit 0. KNOWN_HAND_SPELLINGS is untouched and still new Map([]); no stale-row error,
which is what the gate prints when a ledger row names a defect it no longer finds.

The green is a reading, not an absence. --list shows the edited block among the pairs
the gate actually compared:

useNavigationOverlay.navigation <- resolveRecordSourceObjectName  (3 call site(s))
useNavigationOverlay.objectName <- resolveRecordSourceObjectName  (3 call site(s))

The gate's own collapse guard (files < 200 || readers < 5 || documented < 5) also passed.
Its pin test scripts/__tests__/check-doc-example-shared-reader.test.ts was run because this
change moves the gate's input population — it adds resolveRecordSourceConfig as a newly
visible documented symbol in useNavigationOverlay.ts, which the gate then compares and finds
nothing on: 22 passed (22), exit 0.

⛔ scripts/check-doc-example-shared-reader.mjs is not modified. Its condition (a) requires
the example to call a symbol the repository exports, so getDataConfig never formed a pair and
this class was invisible to it by construction. That narrowing is deliberate and is left alone;
the fact is recorded on the card, which is where it belongs.

Census: which other @example teaches getDataConfig?

Zero outside this PR's surface. A JSDoc-block scan over every tracked .ts/.tsx under
packages/, restricted to lines inside an @example section, finds exactly 2 — both of
them the two fixed here:

@example lines mentioning getDataConfig: 2
  packages/core/src/utils/record-source.ts:71  (@example at :69)
  packages/react/src/hooks/useNavigationOverlay.ts:213  (@example at :211)

Nothing outside the surface, so no card is filed for this census.

Measured but deliberately not fixed (running prose, not a copyable @example, and outside
the repair this card authorises): record-source.ts still names getDataConfig at :28, :50
and :65. :28 is a verbatim quotation of the published contract face — the .describe
text on objectql.zod.ts:656 — and editing a quotation so it no longer matches its source
would be worse than leaving it. :50 and the @param dataConfig at :65 describe what callers
hand in, which remains literally true of the two wrapper sites. The gate's own documented limit
2 ("prose outside a fenced @example") is the same boundary. Flagged here for triage rather
than changed in passing.

Changeset gate — verdict lines verbatim

Before, node scripts/check-changeset-presence.mjs (exit 1):

❌  2 source file(s) of 2 released package(s) changed, and this change adds no changeset:

.changeset/7798-getdataconfig-doc-example.md was added in the empty-frontmatter form
(this change releases nothing — it is doc comments). After (exit 0):

✅  2 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/7798-getdataconfig-doc-example.md.
    Every one of them has an EMPTY frontmatter — declared as releasing nothing, which
    is the explicit exemption and a complete answer to this gate.

node scripts/check-changeset-no-major.mjs → ✅ No changeset declares a 'major' bump. (exit 0).

Everything else run, at commit 9116631c4

The union below was re-run after the final commit, on a clean tree, so these readings are
of the tree this PR actually carries.

gate verdict line exit
check:doc-example-readers OK 80 documented symbol(s), 3944 call site(s), 11 slot(s)... 0
check:control-bytes ✅ check-control-bytes: OK (scanned 6358 tracked text file(s); skipped 85 binary). 0
check:spec-symbols ✅ spec member citations: no comment cites a key its spec symbol does not declare. 0
check:doc-fences ✅ check:doc-fences — every TypeScript block in 227 document(s) is fenced ts/tsx/typescript... 0
check-changeset-presence.mjs ✅ ...declares 1 changeset(s) 0
check-changeset-no-major.mjs ✅ No changeset declares a 'major' bump. 0
turbo run type-check --filter=@object-ui/core 3 successful, 3 total 0
turbo run type-check --filter=@object-ui/react 6 successful, 6 total 0
scripts/__tests__/check-doc-example-shared-reader.test.ts 22 passed (22) 0

Every exit code above was captured with the redirect-then-capture form
(cmd > out 2>&1; EXIT=$?), never through a pipe.

Not run, and not claimed: the repository-wide pnpm lint and the full test suite — CI owns
those. scripts/__tests__/check-doc-links.test.ts (the known 15 s shared-box timeout flake) was
not run and nothing here touches it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3


Generated by Claude Code

…hared record source (objectui#7798)

Two doc blocks prescribed, in a copyable `@example`, a line no reader can write:

    const dataConfig = useMemo(() => getDataConfig(schema), [schema]);

`packages/react/src/hooks/useNavigationOverlay.ts` (the `useNavigationOverlay`
block) and `packages/core/src/utils/record-source.ts` (the
`resolveRecordSourceObjectName` block) both spelled it that way, and
`getDataConfig` is exported by nothing — measured, zero rows for
`export function|const|{ getDataConfig` under `packages/`. It survives only as a
file-local wrapper in `plugin-map/src/ObjectMap.tsx` and
`plugin-grid/src/ObjectGrid.tsx`, so outside those two files there is no module
to import it from.

Both wrappers already delegate their ladder to `resolveRecordSourceConfig`,
keeping only the array shorthand above the shared call, so all live sites now
obtain this value the same way — `plugin-calendar` and `plugin-tree` call the
shared producer directly. The examples follow those live call sites, which is
the judgement PR #7797 applied to `navigation-overlay.tsx`: follow the live call
sites, not another doc block. `useNavigationOverlay`'s example also names the
import, so the line it teaches is copyable as written; `record-source.ts` needs
none, and its example is now byte-identical to the `resolveRecordSourceConfig`
example seventy lines below it in the same file.

`scripts/check-doc-example-shared-reader.mjs` cannot see this class by
construction — its condition (a) requires the example to call a symbol the
repository exports, and `getDataConfig` is exported by nothing, so the pair is
never formed. That gate is deliberately narrow and is left untouched; the fact
is recorded on the card.

No executable line changes: every added and removed diff line under `packages/`
is a JSDoc continuation line, and both revisions of both files transpile to
byte-identical output at `removeComments: true`.

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

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3187.4 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CnaboxA9.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) 5.13KB 2.35KB
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) 510.60KB 116.20KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 182.08KB 50.62KB
fields (index.js) 242.44KB 61.25KB
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) 4.28KB 1.75KB
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.98KB 10.98KB
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.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.19KB 46.37KB
plugin-dashboard (index.js) 132.88KB 34.69KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
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) 10.35KB 3.60KB
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.74KB 1.41KB
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

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.

finding(docs): two doc blocks teach , a helper no package exports — and the #7652 gate cannot see it

1 participant