React Integration Patterns
The @naylence/react package provides a set of hooks and components to integrate Naylence agents and fabric connectivity into React applications. This guide outlines the essential usage patterns for building React-based Naylence apps.
Installation
To get started, install the React integration package along with the Agent SDK:
npm install @naylence/reactFabric Provider
The foundation of any Naylence React application is the FabricProvider. It manages the lifecycle of the FameFabric instance, handling connection and cleanup automatically.
Wrap your application (or the part of it that needs connectivity) with FabricProvider:
import { FabricProvider } from '@naylence/react';
import { clientConfig } from './config';
function App() {
return (
<FabricProvider opts={clientConfig}>
<YourAppContent />
</FabricProvider>
);
}Accessing Fabric State
Use the useFabric hook to access the current fabric instance and its connection status. This is useful for showing connection states or handling errors.
import { useFabric } from '@naylence/react';
export function ConnectionStatus() {
const { fabric, status, error } = useFabric();
if (error) return <div>Error: {String(error)}</div>;
if (status !== 'ready') return <div>Connecting...</div>;
return <div>Connected to Fabric</div>;
}Consuming Remote Agents
The most common pattern for client-side components is to consume a remote agent. The useRemoteAgent hook simplifies creating a typed proxy to a remote service.
import { useRemoteAgent } from '@naylence/react';
import type { HelloAgent } from './HelloAgent';
export function ClientComponent() {
// Get a typed proxy to the remote agent
const agent = useRemoteAgent<HelloAgent>('hello@fame.fabric');
const handleClick = async () => {
if (!agent) return;
const response = await agent.runTask({ message: 'Hello' });
console.log(response);
};
return (
<button onClick={handleClick} disabled={!agent}>
Call Agent
</button>
);
}Hosting Agents in the Browser
You can also host agents directly in the browser (e.g., for a Sentinel node or a peer-to-peer application). Use useFabricEffect to register the agent when the fabric becomes ready.
import { useFabricEffect } from '@naylence/react';
import { MyLocalAgent } from './MyLocalAgent';
export function ServiceComponent() {
useFabricEffect((fabric) => {
const agent = new MyLocalAgent();
// Serve the agent on the fabric
fabric.serve(agent, 'my-service@fame.fabric');
// Cleanup function (optional)
return () => {
// Custom cleanup if needed
};
}, []); // Dependencies
return <div>Service is running</div>;
}Configuration for Browser Communication
When hosting agents in the browser (e.g., a Sentinel node) and connecting to them from other components (Client nodes), you need to configure the BroadcastChannelListener and BroadcastChannelConnectionGrant.
This setup allows different parts of your application (or different tabs) to communicate via the browser’s BroadcastChannel API.
It is recommended to generate a unique channel name for each application session to prevent interference between multiple tabs running the same application.
import { generateId } from '@naylence/core';
// Generate a unique channel name for this page session
// This prevents interference between multiple tabs running the same app
const pageId = generateId();
const channelName = `default-${pageId}`;
// Sentinel (Host) Configuration
export const sentinelConfig = {
rootConfig: {
node: {
type: 'Sentinel',
requestedLogicals: ['fame.fabric'],
listeners: [
{
type: 'BroadcastChannelListener',
channelName,
},
],
security: {
type: 'DefaultSecurityManager',
security_policy: {
type: 'NoSecurityPolicy',
},
authorizer: {
type: 'NoopAuthorizer',
},
},
},
},
};
// Client Configuration
export const clientConfig = {
rootConfig: {
node: {
hasParent: true,
requestedLogicals: ['fame.fabric'],
admission: {
type: 'DirectAdmissionClient',
connectionGrants: [
{
type: 'BroadcastChannelConnectionGrant',
purpose: 'node.attach',
channelName,
ttl: 0,
durable: false,
},
],
},
security: {
type: 'DefaultSecurityManager',
security_policy: {
type: 'NoSecurityPolicy',
},
authorizer: {
type: 'NoopAuthorizer',
},
},
},
},
};Agent Definition
Agents in React applications follow the same pattern as standard Naylence agents, extending BaseAgent.
import { BaseAgent } from '@naylence/agent-sdk';
export class HelloAgent extends BaseAgent {
async runTask(payload: { message: string }): Promise<string> {
return `Received: ${payload.message}`;
}
}