'use client' // AUTO-GENERATED by mizan — do not edit import { createContext, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore, type ReactNode, } from 'react' import { configure, initSession, mizanCall, mizanFetch, MizanError, registerContext, type ContextState, } from '@mizan/base' {% if !stage1_imports.is_empty() -%} import { {{ stage1_imports|join(", ") }} } from './index' {% endif -%} // Internal — runs inside a Provider, registers with the kernel exactly once. function useContextSubscription( name: string, params: Record, fetchFn: () => Promise, initialData?: T, ): ContextState { const ref = useRef | null>(null) if (!ref.current) { ref.current = registerContext(name, params, fetchFn, initialData) } const handle = ref.current useEffect(() => { if (handle.getState().status === 'idle') handle.refetch() return () => handle.unregister() }, [handle]) return useSyncExternalStore(handle.subscribe, handle.getState, handle.getState) } // Internal — wraps an imperative call() with isPending / error state. interface MutationHook { mutate: (args: TArgs) => Promise isPending: boolean error: Error | null } function useMutation( callFn: (args: TArgs) => Promise, ): MutationHook { const [isPending, setIsPending] = useState(false) const [error, setError] = useState(null) const mutate = useCallback(async (args: TArgs) => { setIsPending(true) setError(null) try { return await callFn(args) } catch (e) { setError(e as Error) throw e } finally { setIsPending(false) } }, [callFn]) return { mutate, isPending, error } } {% if has_global %} // ── Global Context ── const GlobalCtx = createContext | null>(null) export function GlobalContextProvider({ children }: { children: ReactNode }) { const ssrData = typeof window !== 'undefined' ? (window as any).__MIZAN_SSR_DATA__ : undefined const state = useContextSubscription('global', {}, () => fetchGlobalContext({} as any), ssrData) return {children} } export function useGlobalContext(): ContextState { const ctx = useContext(GlobalCtx) if (!ctx) throw new Error('useGlobalContext requires or ') return ctx } {% for fn in global_fns %} export function use{{ fn.pascal }}(): {{ fn.output_type }} | null { return useGlobalContext().data?.{{ fn.name }} ?? null } {% endfor -%} {% endif -%} {% for ctx in named_contexts %} // ── {{ ctx.pascal }} Context ── const {{ ctx.pascal }}Ctx = createContext | null>(null) {% if ctx.has_params -%} export function {{ ctx.pascal }}Context({ children, ...params }: {{ ctx.pascal }}ContextParams & { children: ReactNode }) { const state = useContextSubscription('{{ ctx.name }}', params, () => fetch{{ ctx.pascal }}Context(params)) return <{{ ctx.pascal }}Ctx.Provider value={state}>{children} } {% else -%} export function {{ ctx.pascal }}Context({ children }: { children: ReactNode }) { const state = useContextSubscription('{{ ctx.name }}', {}, () => fetch{{ ctx.pascal }}Context({} as any)) return <{{ ctx.pascal }}Ctx.Provider value={state}>{children} } {% endif %} export function use{{ ctx.pascal }}Context(): ContextState<{{ ctx.pascal }}ContextData> { const ctx = useContext({{ ctx.pascal }}Ctx) if (!ctx) throw new Error('use{{ ctx.pascal }}Context requires <{{ ctx.pascal }}Context>') return ctx } {% for fn in ctx.fns %} export function use{{ fn.pascal }}(): {{ fn.output_type }} | null { return use{{ ctx.pascal }}Context().data?.{{ fn.name }} ?? null } {% endfor -%} {% endfor -%} {% for call in calls %} {% if call.has_input -%} export function use{{ call.pascal }}() { return useMutation[0], Awaited>>(call{{ call.pascal }}) } {% else -%} export function use{{ call.pascal }}() { return useMutation>>(() => call{{ call.pascal }}() as any) } {% endif -%} {% endfor %} // ── MizanContext root provider ── export interface MizanContextProps { /** Base URL for protocol endpoints. Defaults to "/api/mizan". */ baseUrl?: string /** Set to `false` for backends without a `/session/` endpoint (e.g. FastAPI). */ session?: boolean children: ReactNode } /** * Root provider — calls configure() once and mounts the global context (if defined). * Must wrap any component using Mizan-generated hooks. */ export function MizanContext({ baseUrl, session, children }: MizanContextProps) { const configured = useRef(false) if (!configured.current) { const opts: Parameters[0] = {} if (baseUrl !== undefined) opts.baseUrl = baseUrl if (session !== undefined) opts.session = session if (Object.keys(opts).length > 0) configure(opts) configured.current = true } {%- if has_global %} return {children} {%- else %} return <>{children} {%- endif %} } // ── Imperative escape hatch ── /** * Returns the imperative kernel API. For test harnesses or rare cases where * a typed generated hook does not fit. Most app code should use the typed hooks. */ export function useMizan() { return { call: mizanCall, fetch: mizanFetch } } export type { ContextState } from '@mizan/base' export { configure, initSession, MizanError } from '@mizan/base'