From f81d879f4474ef7e6aaceb9f840ada09d311b584 Mon Sep 17 00:00:00 2001 From: objectui-agent Date: Sun, 6 Sep 2026 02:39:32 +0000 Subject: [PATCH] =?UTF-8?q?docs(react):=20shrink=20UNGATED=5FDOCS=20by=20o?= =?UTF-8?q?ne=20=E2=80=94=20the=20react=20README's=2011=20blocks=20compile?= =?UTF-8?q?=20(#5174=20batch=2012)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `packages/react/README.md` leaves the `check-doc-snippet-types` coverage ledger. All 11 of its `ts`/`tsx` snippets are now compiled, `--strict`, against the packages' built `dist/*.d.ts`: zero `FRAGMENT_MARKER` declarations added, zero `UNGATED_DOCS` entries added, so the ledger hunk is 0 additions / 2 deletions. Seven blocks failed before this change and each is repaired at the document, never by weakening the gate: * `useSchemaContext` taught an API that does not exist. It destructured `data` and `updateData`; the shipped `SchemaRendererContextType` declares `dataSource`, `debug`, `debugFlags` and `apiFetch` and neither of those two names. The example now reads what the context carries and points record data at `useDataScope`, which is the hook that answers it. * The `NON_GRID_ROW_CEILING` block did not parse. Its destructuring statement ended without a semicolon and the next statement opens with `<`, so ASI does not fire and the call is parsed as the left side of a relational expression — a reader who copied the block hit the same five syntax errors the gate did. * The remaining five carried ambient names the page never defined. Those are now `declare const` against the shipped types, following the pattern `packages/data-objectstack/README.md` already uses. Two claims the prose only asserted are now enforced by the compiler: `OBJECT_GRID_BINDING` is annotated `ElementDataSourceMapping`, so a key the block does not read is rejected rather than accepted and dropped, and `notify()`'s severity and displayType literals are checked against the spec unions. Gate strictness is unchanged: the file is touched only inside the `UNGATED_DOCS` object literal, and everything from the `Fence scanning` banner to EOF is byte-identical to `origin/main`. Part of #5174 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M --- packages/react/README.md | 64 +++++++++++++++++++++++------ scripts/check-doc-snippet-types.mjs | 2 - 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/packages/react/README.md b/packages/react/README.md index 332177307..f135b3e47 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -72,14 +72,19 @@ function App() { ```tsx import { SchemaRenderer } from '@object-ui/react' +import type { BaseSchema } from '@object-ui/types' + +declare const formSchema: BaseSchema function App() { - const handleSubmit = (data) => { + const handleSubmit = (data: Record) => { console.log('Form submitted:', data) } + // `onSubmit` is not a prop `SchemaRenderer` reads: it is forwarded to the + // component the schema names, which is why the props type stays open. return ( - @@ -93,7 +98,13 @@ Injects the host's data source (and optional capabilities) into every renderer below it: ```tsx -import { SchemaRendererProvider } from '@object-ui/react' +import { SchemaRenderer, SchemaRendererProvider } from '@object-ui/react' +import type { ApiFetch } from '@object-ui/react' +import type { BaseSchema, DataSource } from '@object-ui/types' + +declare const adapter: DataSource +declare const authenticatedFetch: ApiFetch +declare const schema: BaseSchema {data.value} + const { dataSource, debug } = useSchemaContext() + const value = useDataScope('value') + + if (!dataSource) return null + return
{String(value)}
} ``` @@ -136,14 +151,20 @@ views so `view` can be matched); these two apply the composed result to the block's schema and render the two non-final states. ```tsx +import type { FC } from 'react' import { ElementDataSourceGate } from '@object-ui/react' +import type { ElementDataSourceMapping } from '@object-ui/react' // The seam is imported from CORE, not from here — see the note below. import { elementDataSourceBlock } from '@object-ui/core' +import type { BaseSchema } from '@object-ui/types' + +// The block this renderer wraps — whatever the registry resolves for its type. +declare const ObjectGrid: FC<{ schema: BaseSchema }> // `mapping` names ONLY the keys this block reads. A composed value written onto // a key the block ignores would be accepted and silently dropped — the defect // the binding exists to remove. -const OBJECT_GRID_BINDING = { +const OBJECT_GRID_BINDING: ElementDataSourceMapping = { columns: true, // the view's FIELD list may fill `schema.columns` filter: true, // AND-combined, never replaced ("additional criteria") sort: true, @@ -151,7 +172,7 @@ const OBJECT_GRID_BINDING = { } // `elementDataSourceBlock` is not optional decoration — see below. -const ObjectGridRenderer = elementDataSourceBlock(({ schema, ...props }) => ( +const ObjectGridRenderer = elementDataSourceBlock>(({ schema, ...props }) => ( {(bound) => } @@ -204,9 +225,17 @@ waits on `ready` — stays a per-component decision; this hook only owns the resolution. ```tsx +import { useEffect } from 'react' import { useSettledSchema } from '@object-ui/react' - -function ObjectSomething({ schema, dataSource }) { +import type { DataSource } from '@object-ui/types' + +function ObjectSomething({ + schema, + dataSource, +}: { + schema: { objectName?: string } + dataSource: DataSource +}) { const key = schema.objectName ?? '' const { ready, def } = useSettledSchema(key, dataSource) @@ -235,12 +264,19 @@ import { applyNonGridRowCeiling, NonGridRowCeilingNote, } from '@object-ui/react' +import type { DataSource, QueryParams } from '@object-ui/types' + +declare const dataSource: DataSource +declare const objectName: string +declare const schema: { filter?: QueryParams['$filter'] } const result = await dataSource.find(objectName, { $filter: schema.filter, $top: NON_GRID_ROW_CEILING_TOP, // the ceiling plus ONE probe row }) -const { rows, total, truncated } = applyNonGridRowCeiling(result) +// The semicolon is load-bearing: the next statement opens with `<`, so without +// it the call above is parsed as the left side of a relational expression. +const { rows, total, truncated } = applyNonGridRowCeiling(result); // …draw `rows`, then: ``` @@ -328,6 +364,8 @@ belong (a banner is in flow, an inline notification sits next to its raiser). why every type looked like a toast. ```tsx +import { useNotifications } from '@object-ui/react' + const { notify } = useNotifications() notify({ title: 'Saved', severity: 'success' }) // toast (spec default) diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs index d62916c55..32cd6533d 100644 --- a/scripts/check-doc-snippet-types.mjs +++ b/scripts/check-doc-snippet-types.mjs @@ -757,8 +757,6 @@ const UNGATED_DOCS = { '7 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2741x1 — candidate real defects, un-triaged', 'packages/react-runtime/README.md': '25 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2813x1 TS2814x1 — candidate real defects, un-triaged', - 'packages/react/README.md': - '9 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2339x2 — candidate real defects, un-triaged', 'packages/types/README.md': '3 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 3 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', };