call-core
v0.0.1
Published
React components and hooks for SignalWire calling functionality.
Readme
Call Core
React components and hooks for SignalWire calling functionality.
Components and Hooks
1. <SignalWireClient token={string} />
Context provider that creates and manages a SignalWire client instance. Designed to work with React strict mode.
import { SignalWireClient } from "call-core";
function App() {
return (
<SignalWireClient token="your-signalwire-token">
{/* Your app components */}
</SignalWireClient>
);
}Features:
- Creates SignalWire client with provided token
- Handles client initialization and cleanup
- Works with React strict mode (prevents double initialization)
- Exposes client and connection status via context
2. useSignalWire()
Hook that returns the SignalWire client from context. Must be used within a SignalWireClient.
import { useSignalWire } from "call-core";
function MyComponent() {
const client = useSignalWire(); // Returns SignalWireClient instance
// Use client for SignalWire operations
}Returns:
SignalWireClient- The initialized client instance
Errors:
- Throws if used outside
SignalWireClientcontext - Throws if client is not initialized yet
3. <Call to={string} />
Context provider that manages call state for a specific destination.
import { Call } from "call-core";
function App() {
return (
<SignalWireClient token="token">
<Call to="+1234567890">{/* Call-related components */}</Call>
</SignalWireClient>
);
}Props:
to: string- The destination to call (phone number, SIP address, etc.)children: ReactNode- Child components
4. useCall()
Hook that provides call functionality and state. Must be used within a Call component.
import { useCall } from "call-core";
function CallControls() {
const { call, isDialing, to, dial, start, hangup } = useCall();
const handleDialAndStart = async () => {
await dial(); // Creates the room session with Call props
await start(); // Starts the room session
};
return (
<div>
<p>Calling: {to}</p>
<p>Status: {call ? "Connected" : "Disconnected"}</p>
<button onClick={handleDialAndStart} disabled={isDialing || !!call}>
{isDialing ? "Dialing..." : "Call"}
</button>
<button onClick={hangup} disabled={!call}>
Hang Up
</button>
</div>
);
}Returns:
call: FabricRoomSession | null- The active call session (if dialed)isDialing: boolean- Whether a call is currently being initiatedto: string- The destination number/address from Call propsdial: (options?: Partial<DialParams>) => Promise<void>- Function to dial and create room sessionstart: () => Promise<void>- Function to start the room sessionhangup: () => Promise<void>- Function to hangup and end the call
File Structure
src/lib/
├── contexts/
│ ├── SignalWireContext.tsx # SignalWireClient component and context
│ └── CallContext.tsx # Call component and context
├── hooks/
│ ├── useSignalWire.ts # Hook to access SignalWire client
│ └── useCall.ts # Hook to manage calls
└── index.ts # Main exportsUsage Example
See packages/call-ui/src/App.tsx for a complete example.
Architecture
The system is designed with the following flow:
- SignalWireClient creates and manages the SignalWire client instance
- Call context provides the dial/start/hangup functionality for a specific destination
- useCall hook exposes the call functionality from the nearest Call context
Key Design Decisions
- Reactive State: Client state is managed with both ref (for single instance) and state (for reactivity)
- Context-based API: Call functionality is provided through Call context, not through useCall hook
- Separation of Concerns:
dial()creates the room session using Call propsstart()starts the room sessionhangup()ends the room session
Implementation Status
✅ Completed:
- SignalWire client initialization and cleanup
- Reactive client state management
- Call context with dial/start/hangup functions
- Proper error handling
- React strict mode compatibility
📋 TODO (Optional Enhancements):
- Add call event listeners (connected, disconnected, error, etc.)
- Add call quality metrics
- Add push notification handling
Building
# Build the library
npm run lib:build
# Build for development
npm run dev