React wrapper-layer codegen — restore the idioms over the kernel

The harness was written against the MIZAN.md oracle (<MizanContext>,
provider-per-context, useMizan, etc.) but the codegen had been narrowed
to just hooks-direct-on-kernel after the kernel split. Restoring the
React-idiomatic layer on top of the kernel.

backends/mizan-django/generate/generator/lib/adapters/react.mjs:
- Emits <MizanContext baseUrl="…"> root provider that calls configure()
  once and (if a global context is registered) wraps children in
  <GlobalContextProvider>.
- Emits <GlobalContextProvider> + <{Name}Context> per named context —
  kernel registration happens once per provider mount, not per hook
  call. Consumers read from React Context.
- Base hooks: useGlobalContext() / use{Name}Context() return full
  ContextState<T> (data + status + error).
- Convenience hooks per context-function (use{Fn}() returns data | null)
  and per regular function/mutation (use{Fn}() returns
  { mutate, isPending, error }).
- useMizan() returns { call, fetch } as an imperative escape hatch
  for test harnesses or rare cases where typed hooks don't fit.
- Re-exports MizanError, configure, initSession, ContextState from
  @mizan/base.

backends/mizan-django/generate/generator/cli.mjs:
- After Stage 2, appends `export * from './<adapter>'` to index.ts so
  `import { useEcho, MizanContext } from './api'` works as a barrel.

Bug fixes surfaced during integration:
- react.mjs was generating `from '../index'` (wrong path); flat layout
  needs `./index`.
- harness django.config.mjs had `output: 'src/api/generated.ts'` which
  the codegen treated as a directory; corrected to `output: 'src/api'`.
- example testapp/clients.py imported from the deleted
  mizan.setup.registry path; routed through mizan.setup aggregator.

harness/package.json: adds @mizan/base dep so the generated react.tsx
can resolve its kernel imports.

harness/src/fixtures.tsx:
- DjangoError → MizanError (kernel error class, backend-agnostic).
- useChatChannel sourced from ./api/channels.hooks directly (not
  re-exported from the unified index for now).
- Form fixtures removed — forms codegen deferred per Blazr scope.

Verified: harness `vite build` succeeds, 53 modules transformed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-06 17:21:49 -04:00
parent 63c9a9c4ce
commit 2982741aad
26 changed files with 364 additions and 491 deletions

View File

@@ -148,6 +148,18 @@ async function generate(config, options = {}) {
}
}
// Append Stage 2 re-exports to index.ts so `import { useEcho, MizanContext } from './api'` works
const adapterExports = targets
.map(t => ({ react: 'react', vue: 'vue', svelte: 'svelte' })[t])
.filter(Boolean)
.map(name => `export * from './${name}'`)
.join('\n')
if (adapterExports) {
const indexPath = path.join(fullOutputDir, 'index.ts')
const existing = await fs.readFile(indexPath, 'utf8')
await writeOutput(indexPath, `${existing}\n// Stage 2 framework adapter\n${adapterExports}\n`)
}
// Schema JSON
await writeOutput(
path.join(fullOutputDir, 'schema.json'),