Repository navigation
Commit ef025fe
refactor(react): AdapterCtx and useAdapter are typed by DataSource; react drops its data-objectstack dependency (#26292)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9CXkMCRg8Z8RTFcd3HfPqhC)_
Fixes #25917
`@object-ui/react` no longer depends on `@object-ui/data-objectstack`.
`AdapterCtx` and `useAdapter()` are typed by the protocol-level
`DataSource` from `@object-ui/types`, and a host that installs a
concrete adapter declares it once on a new extension point,
`AdapterContextRegister` (module augmentation, the same shape as
TanStack Router's `Register`). The `enable`-block denial predicate moves
to `@object-ui/core`, and the adapter re-exports it unchanged.
Clause-②: yes (narrowing)
Metadata-protocol: none
## Premise, measured on origin/main 4f7e041
- The card counted 28 `components` files reaching the concrete adapter.
That count is stale: today there are 62 non-test readers of `useAdapter`
/ `AdapterCtx` (app-shell 41, console 14, components 4, plugin-designer
3).
- 18 of them read `ObjectStackAdapter` members that `DataSource` does
not declare: `getClient` (13 files), `probeAppAccess`,
`probeMetaItemAccess`, `getConnectionState` / `onConnectionStateChange`,
`clearCache`, `queryDataset`. They all sit in app-shell, console and
plugin-designer, which already depend on the adapter.
- `isApiAccessDeniedError` is also called inside `data-objectstack`, so
`core` is its only single-source home: both `react` and
`data-objectstack` depend on `core`.
- The seat chose the route (register augmentation over 18 call-site
guards) and amended the claim surface to cover core, data-objectstack
and the host declarations.
## What changed
- **`@object-ui/react`**: `AdapterCtx` / `useAdapter()` carry
`ContextAdapter`, which resolves to the adapter a host declares on
`AdapterContextRegister` and otherwise to `DataSource`.
`@object-ui/data-objectstack` moves to `devDependencies`, because one
boundary test (`error-message.normalisation-boundary.test.ts`) still
reads it. `error-message.ts` imports the predicate from
`@object-ui/core`. The README documents the extension point.
- **`@object-ui/core`**: new `utils/api-access-denied.ts` holds
`API_ACCESS_DENIED_CODES` and `isApiAccessDeniedError`, moved verbatim
with their docblock.
- **`@object-ui/data-objectstack`**: re-exports both names from
`@object-ui/core`, so its published face is unchanged, and its internal
caller imports the predicate from core.
- **`@object-ui/app-shell`**: `adapter-context-register.ts` declares
`ObjectStackAdapter`, and the package entry imports it, so the
declaration ships in `dist/index.d.ts`.
- **`@object-ui/plugin-designer`**: the same declaration, imported by
the two pages that call `getClient`, so the test type-check program sees
it too.
- **sdui**: `core` and `react` re-recorded. `data-objectstack.json` is
removed by the generator ("no longer reached"), because the registry
walk reached it only through react.
No call site of the 18 changed. Runtime behaviour is unchanged: the
context holds the same object.
## Verification (merged main 2409c9c, head 29b4eed, all heavy runs
under `os-verify-lock`)
- Build: `turbo run build --filter=@object-ui/console`, 71/71 tasks,
which includes the Console build.
- `type-check`: core, react, data-objectstack, components,
plugin-designer, app-shell and console all exit 0. Console resolves
`@object-ui/react` and `@object-ui/app-shell` from `dist`, and its seven
files that call `getClient` through app-shell's `useAdapter` compile, so
the published app-shell types carry the declaration.
- Published-types probe (one-off, deleted afterwards): a file under
`ui/apps/console` that imports type-only from `@object-ui/app-shell` and
reads `useAdapter()?.getClient()` exits 0. The same file without the
app-shell import exits 2 with TS2339, `Property 'getClient' does not
exist on type 'DataSource'` (the compiler prints the type with its `any`
argument).
- New pin `AppShellContext.adapterType.pin.test.ts` (13 cases, same tsc
harness as `SchemaRendererContext.dataSourceType.pin.test.ts`). Without
a declaration, `getClient` and `probeAppAccess` are refused and any
`DataSource` may be provided. With a declaration, the host adapter's own
member is readable and a bare `DataSource` provider value is refused.
CONTROL rows guard against a harness that has degraded to `any`.
- Mutations through `scripts/ablation-replace.mjs`, each restored to the
HEAD blob with an empty `git diff HEAD`:
- Typing the context as `any` turns 2 cases red: the provider check and
a CONTROL row.
- Widening the `DataSource` fallback with `getClient` / `probeAppAccess`
turns 3 cases red: both NARROWED rows and the provider row.
- vitest over `packages/react/`, `packages/core/`,
`packages/data-objectstack/` and `packages/plugin-designer/`: 480 files
and 7238 tests passed, 27 skipped. app-shell's suite is left to CI `Test
Core` / Test UI because its runtime is untouched (type declaration
only).
- Gates: the 64 families `dispatch-gates --commands` derived were run
and reconciled with `--ran`. 63 exit 0. `check:dual-build-cjs-loads`
exits 3 (PREREQUISITE NOT MET: it reads the whole repo's built output),
so it is NOT MEASURED locally and left to CI.
`check-adr-0087-registration` verifies `not-required
(runtime-interface-only ...#ContextAdapter)`.
`check:new-line-citations`: 0 new citations. eslint on the changed
files: 0 errors.
- Dogfood: owed once on the final head (Clause-② narrowing). It runs
after the next main merge, and the os-dev report carries its reading.
## Acceptance notes
- The changeset carries a FROM → TO fix block, as the seat asked:
declare the adapter, or narrow at the call site.
`runtime-interface-only` inherits the prescription refusal, and the
detector does not read this block as a prescription. The disposition
stands on the compiler channel: a reader that needs the declaration gets
`TS2339` at its own call site, and no metadata surface moves.
- `plugin-designer` needed the declaration imported by its pages, not
only placed under `src/`. Its `tsconfig.test.json` compiles the pages
through the test files, and that program never includes a file that
nothing imports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017sGTFTS9edirCTVBgQysK7
---
_Generated by [Claude
Code](https://claude.ai/code/session_017sGTFTS9edirCTVBgQysK7)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e14d9ce commit ef025fe
18 files changed
Lines changed: 478 additions & 61 deletions
File tree
- .changeset
- scripts/sdui-manifest.sources
- ui/packages
- app-shell/src
- core/src
- utils
- data-objectstack/src
- plugin-designer/src
- pages
- react
- src
- context
- __tests__
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
11 | 15 | | |
12 | 16 | | |
13 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
43 | 46 | | |
44 | 47 | | |
45 | 48 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
| |||
1017 | 1018 | | |
1018 | 1019 | | |
1019 | 1020 | | |
1020 | | - | |
1021 | | - | |
1022 | | - | |
1023 | | - | |
1024 | | - | |
1025 | | - | |
1026 | | - | |
1027 | | - | |
1028 | | - | |
1029 | | - | |
1030 | | - | |
1031 | | - | |
1032 | | - | |
1033 | | - | |
1034 | | - | |
1035 | | - | |
1036 | | - | |
1037 | | - | |
1038 | | - | |
1039 | | - | |
1040 | | - | |
1041 | | - | |
1042 | | - | |
1043 | | - | |
1044 | | - | |
1045 | | - | |
1046 | | - | |
1047 | | - | |
1048 | | - | |
1049 | | - | |
1050 | | - | |
1051 | | - | |
1052 | | - | |
1053 | | - | |
1054 | | - | |
1055 | | - | |
1056 | | - | |
1057 | | - | |
1058 | | - | |
1059 | | - | |
1060 | | - | |
1061 | | - | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
1062 | 1026 | | |
1063 | 1027 | | |
1064 | 1028 | | |
| |||
0 commit comments