Rename the package from djarea to mizan across the entire codebase — Python package, React library, generators, tests, and examples. Fix JSX/hook casing (MizanProvider, useMizan, etc.) that broke when the original PascalCase names were lowercased during the rename. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* React context for mizan/channels
|
|
*/
|
|
|
|
import { createContext, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
|
|
import { ChannelConnection, type ChannelConnectionOptions } from './connection'
|
|
import type { ConnectionStatus } from './types'
|
|
|
|
interface ChannelContextValue {
|
|
connection: ChannelConnection
|
|
status: ConnectionStatus
|
|
}
|
|
|
|
const ChannelContext = createContext<ChannelContextValue | null>(null)
|
|
|
|
export interface ChannelProviderProps {
|
|
children: ReactNode
|
|
|
|
/** WebSocket URL (default: /ws/) */
|
|
url?: string
|
|
|
|
/** Reconnect on disconnect (default: true) */
|
|
reconnect?: boolean
|
|
|
|
/** Reconnection delay in ms (default: 1000) */
|
|
reconnectDelay?: number
|
|
|
|
/** Maximum reconnection attempts (default: 10) */
|
|
maxReconnectAttempts?: number
|
|
|
|
/** Connect automatically on mount (default: true) */
|
|
autoConnect?: boolean
|
|
|
|
/** Custom connection instance (for testing) */
|
|
connection?: ChannelConnection
|
|
}
|
|
|
|
export function ChannelProvider({
|
|
children,
|
|
url,
|
|
reconnect,
|
|
reconnectDelay,
|
|
maxReconnectAttempts,
|
|
autoConnect = true,
|
|
connection: providedConnection,
|
|
}: ChannelProviderProps) {
|
|
const connectionRef = useRef<ChannelConnection | null>(null)
|
|
|
|
// Use provided connection or create one
|
|
if (!connectionRef.current) {
|
|
connectionRef.current = providedConnection ?? new ChannelConnection({
|
|
url,
|
|
reconnect,
|
|
reconnectDelay,
|
|
maxReconnectAttempts,
|
|
})
|
|
}
|
|
|
|
const connection = connectionRef.current
|
|
|
|
// Track status for context value
|
|
const [status, setStatus] = useState<ConnectionStatus>(connection.status)
|
|
|
|
useEffect(() => {
|
|
const unsubscribe = connection.onStatusChange(setStatus)
|
|
|
|
if (autoConnect) {
|
|
connection.connect()
|
|
}
|
|
|
|
return () => {
|
|
unsubscribe()
|
|
connection.disconnect()
|
|
}
|
|
}, [connection, autoConnect])
|
|
|
|
const value = useMemo(() => ({
|
|
connection,
|
|
status,
|
|
}), [connection, status])
|
|
|
|
return (
|
|
<ChannelContext value={value}>
|
|
{children}
|
|
</ChannelContext>
|
|
)
|
|
}
|
|
|
|
export function useChannelContext(): ChannelContextValue {
|
|
const context = useContext(ChannelContext)
|
|
if (!context) {
|
|
throw new Error('useChannelContext must be used within a ChannelProvider')
|
|
}
|
|
return context
|
|
}
|
|
|
|
export function useChannelStatus(): ConnectionStatus {
|
|
const { status } = useChannelContext()
|
|
return status
|
|
}
|