112 lines
3.0 KiB
Markdown
112 lines
3.0 KiB
Markdown
# @rythazhur/mizan (TypeScript)
|
|
|
|
React client for the mizan framework. See the [monorepo root](../README.md) for full documentation.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
npm install @rythazhur/mizan@git+https://git.impactsoundworks.com/isw/mizan.git#workspace=react
|
|
```
|
|
|
|
## Usage
|
|
|
|
You don't use this package directly. You use the **generated hooks**.
|
|
|
|
This is the pre-kernel React adapter: it ships its own `MizanProvider`
|
|
(`src/context.tsx`) that owns HTTP/WebSocket/CSRF/session/context state
|
|
directly, rather than subscribing to the `@mizan/base` kernel. It is still
|
|
the provider the Django + desktop example wires against. (`DjangoContext`,
|
|
`useDjango`, etc. are deprecated aliases for the `Mizan*` names.)
|
|
|
|
### 1. Configure
|
|
|
|
```toml
|
|
# mizan.toml
|
|
output = "src/api"
|
|
targets = ["react"]
|
|
|
|
[source.django]
|
|
manage_path = "../backend/manage.py"
|
|
command = ["uv", "run", "python"]
|
|
```
|
|
|
|
### 2. Generate
|
|
|
|
The codegen is the `mizan-generate` Rust binary (source at
|
|
`protocol/mizan-codegen/`; `protocol/mizan-generate/` is the npm launcher):
|
|
|
|
```bash
|
|
mizan-generate --config mizan.toml
|
|
```
|
|
|
|
### 3. Wrap your app
|
|
|
|
```tsx
|
|
import { MizanProvider } from '@rythazhur/mizan'
|
|
|
|
<MizanProvider>
|
|
<App />
|
|
</MizanProvider>
|
|
```
|
|
|
|
`MizanProvider` is the only provider you need. It handles HTTP, WebSocket, CSRF, session init, context auto-fetching, and channel connections.
|
|
|
|
### 4. Use generated hooks
|
|
|
|
```tsx
|
|
import { useCurrentUser, useEcho, useContactForm, useChatChannel } from '@/api'
|
|
|
|
// Context (SSR-hydrated, auto-refreshed)
|
|
const user = useCurrentUser()
|
|
|
|
// Server function
|
|
const echo = useEcho()
|
|
const result = await echo({ text: 'hello' })
|
|
|
|
// Form (Zod + server validation)
|
|
const form = useContactForm()
|
|
form.set('email', 'test@example.com')
|
|
await form.submit()
|
|
|
|
// Channel (WebSocket)
|
|
const chat = useChatChannel({ room: 'general' })
|
|
chat.send({ text: 'hello' })
|
|
chat.messages // typed, reactive
|
|
```
|
|
|
|
## Generated Files
|
|
|
|
The Rust codegen emits per-target files into the configured `output`
|
|
directory (Stage 1 is auto-included whenever `react` is a target):
|
|
|
|
| File | Contents |
|
|
|------|----------|
|
|
| `types.ts` | Pydantic types |
|
|
| `contexts/<name>.ts` | Per-context `fetchXxx` bundles |
|
|
| `react.tsx` | `<MizanContext>` provider + typed `use{Hook}()` hooks |
|
|
| `channels.ts` / `channels.hooks.tsx` | Channel types + hooks (when the schema carries channels) |
|
|
| `index.ts` | Stage 1 re-export root |
|
|
|
|
## Sub-exports
|
|
|
|
| Import | When to use |
|
|
|--------|------------|
|
|
| `@rythazhur/mizan` | Core: `MizanProvider`, hooks, forms, errors |
|
|
| `@rythazhur/mizan/channels` | WebSocket channels |
|
|
| `@rythazhur/mizan/jwt` | JWT token management |
|
|
| `@rythazhur/mizan/client` | HTTP clients (CSR/SSR) |
|
|
| `@rythazhur/mizan/allauth` | Allauth UI components |
|
|
|
|
These are **library internals** used by the generated code. You should import from `@/api` (your generated index), not from the library directly.
|
|
|
|
## Running Tests
|
|
|
|
```bash
|
|
# Unit tests (Vitest, jsdom)
|
|
npm test
|
|
|
|
# E2E tests (Playwright, real browser)
|
|
# Requires Docker backend running
|
|
npx playwright test
|
|
```
|