resolvo-cms
Version:
Headless CMS for Resolvo websites with real-time content management
483 lines (372 loc) โข 12.5 kB
Markdown
# Resolvo CMS
A headless CMS package for Resolvo websites with real-time content management, similar to Sanity but integrated with the Resolvo ecosystem.
## Features
- ๐ **Real-time Updates** - Live content synchronization across all connected clients
- ๐ **Schema-based Content** - Define content structures with validation rules
- ๐ง **Type-safe** - Full TypeScript support with generated types
- โก **Performance Optimized** - Intelligent caching with LRU eviction and automatic cleanup
- ๐จ **React Integration** - Hooks and components for seamless React integration
- ๐ **Secure** - Token-based authentication and role-based access control
- ๐ฑ **Responsive** - Mobile-friendly content editor components
- ๐ **Connection Resilience** - Advanced WebSocket connection handling with automatic reconnection
- ๐ **Performance Monitoring** - Built-in performance tracking and metrics
- ๐ก๏ธ **Error Boundaries** - React error boundaries for graceful error handling
- โก **Request Optimization** - Request queuing, retry mechanisms, and exponential backoff
- ๐งน **Memory Management** - Automatic cleanup and memory leak prevention
## Installation
```bash
npm install resolvo-cms
```
## Quick Start
### Basic Usage
```typescript
import { ResolvoCMSClient } from 'resolvo-cms';
const cms = new ResolvoCMSClient({
apiUrl: 'https://api.resolvo.com',
projectId: 123,
websiteToken: 'your-website-token'
});
// Get content
const content = await cms.getContent('content-id');
// Subscribe to real-time updates
cms.subscribe('schema-id', (updatedContent) => {
console.log('Content updated:', updatedContent);
});
```
### React Integration
```typescript
import { useContent, useSchema } from 'resolvo-cms/react';
function MyComponent() {
const { content, loading, error, updateContent } = useContent(client, {
schemaId: 'hero-section'
});
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>{content?.data.title}</h1>
<p>{content?.data.description}</p>
</div>
);
}
```
### Content Editor Component
```typescript
import { ContentEditor } from 'resolvo-cms/react';
function AdminPanel() {
return (
<ContentEditor
client={cms}
schemaId="hero-section"
onSave={(content) => console.log('Saved:', content)}
onPublish={(content) => console.log('Published:', content)}
/>
);
}
```
## API Reference
### ResolvoCMSClient
The main client class for interacting with the CMS.
#### Constructor
```typescript
new ResolvoCMSClient(config: CMSConfig)
```
#### Configuration
```typescript
interface CMSConfig {
apiUrl: string; // Resolvo API URL
projectId: number; // Project ID
websiteToken?: string; // Website token for public access
authToken?: string; // Auth token for admin access
timeout?: number; // Request timeout (default: 10000ms)
retries?: number; // Retry attempts (default: 3)
}
```
#### Methods
##### Schema Management
```typescript
// Create a new schema
await client.createSchema(schema: CreateSchemaRequest): Promise<CMSSchema>
// Get a schema by ID
await client.getSchema(schemaId: string): Promise<CMSSchema>
// Update a schema
await client.updateSchema(schemaId: string, updates: UpdateSchemaRequest): Promise<CMSSchema>
// Delete a schema
await client.deleteSchema(schemaId: string): Promise<void>
// List schemas
await client.listSchemas(query?: { projectId?: number; isActive?: boolean }): Promise<CMSSchema[]>
```
##### Content Management
```typescript
// Create content
await client.createContent(content: CreateContentRequest): Promise<CMSContent>
// Get content by ID
await client.getContent(contentId: string): Promise<CMSContent>
// Get content by schema
await client.getContentBySchema(schemaId: string, options?: { isPublished?: boolean }): Promise<CMSContent[]>
// Update content
await client.updateContent(contentId: string, updates: UpdateContentRequest): Promise<CMSContent>
// Delete content
await client.deleteContent(contentId: string): Promise<void>
// Publish content
await client.publishContent(contentId: string): Promise<CMSContent>
```
##### Real-time Features
```typescript
// Connect to real-time updates
client.connect(wsConfig?: WebSocketConfig): void
// Disconnect
client.disconnect(): void
// Subscribe to content updates
client.subscribe(schemaId: string, callback: Function): void
// Unsubscribe
client.unsubscribe(schemaId: string, callback?: Function): void
```
### React Hooks
#### useContent
Hook for managing content with real-time updates.
```typescript
const { content, loading, error, updateContent, createContent, deleteContent, publishContent } = useContent(client, {
schemaId: 'hero-section',
contentId: 'content-123',
isPublished: true,
autoConnect: true,
realtime: true
});
```
#### useSchema
Hook for managing schemas.
```typescript
const { schema, schemas, loading, error, createSchema, updateSchema, deleteSchema } = useSchema(client, {
schemaId: 'hero-section',
projectId: 123,
isActive: true,
autoConnect: true,
realtime: true
});
```
#### useRealtime
Hook for real-time connection management.
```typescript
const { isConnected, isConnecting, error, connect, disconnect, subscribe, unsubscribe } = useRealtime(client, {
autoConnect: true,
reconnectAttempts: 5,
reconnectDelay: 1000
});
```
### React Components
#### ContentEditor
A complete content editing component with form generation based on schema.
```typescript
<ContentEditor
client={cms}
schemaId="hero-section"
contentId="content-123"
onSave={(content) => console.log('Saved:', content)}
onPublish={(content) => console.log('Published:', content)}
onCancel={() => console.log('Cancelled')}
className="custom-styles"
/>
```
## Schema Definition
Schemas define the structure of your content with fields and validation rules.
```typescript
interface CMSSchema {
id: string;
name: string;
description?: string;
projectId: number;
fields: CMSField[];
isActive: boolean;
version: number;
createdAt: Date;
updatedAt: Date;
}
interface CMSField {
id: string;
name: string;
label: string;
type: FieldType;
required: boolean;
defaultValue?: any;
validation?: ValidationRule[];
options?: FieldOption[];
placeholder?: string;
description?: string;
helpText?: string;
order: number;
group?: string;
config?: Record<string, any>;
}
```
### Field Types
- `text` - Single line text input
- `textarea` - Multi-line text input
- `number` - Numeric input
- `boolean` - Checkbox
- `image` - Image upload
- `file` - File upload
- `select` - Dropdown selection
- `array` - Array of values
- `object` - JSON object
- `rich-text` - Rich text editor
- `date` - Date picker
- `datetime` - Date and time picker
- `color` - Color picker
- `url` - URL input
### Validation Rules
```typescript
interface ValidationRule {
type: 'required' | 'min' | 'max' | 'pattern' | 'email' | 'url' | 'custom';
value?: any;
message?: string;
}
```
## Examples
### Basic Website Integration
```typescript
import { ResolvoCMSClient } from 'resolvo-cms';
const cms = new ResolvoCMSClient({
apiUrl: 'https://api.resolvo.com',
projectId: 123,
websiteToken: 'your-website-token'
});
// Get published content for hero section
const heroContent = await cms.getPublicContent('hero-section');
// Display content
document.getElementById('hero-title').textContent = heroContent[0]?.data.title;
document.getElementById('hero-description').textContent = heroContent[0]?.data.description;
```
### React Website Component
```typescript
import React from 'react';
import { useContent } from 'resolvo-cms/react';
function HeroSection({ client }) {
const { contentList, loading } = useContent(client, {
schemaId: 'hero-section',
isPublished: true
});
if (loading) return <div>Loading...</div>;
const hero = contentList[0];
if (!hero) return null;
return (
<section className="hero">
<h1>{hero.data.title}</h1>
<p>{hero.data.description}</p>
<img src={hero.data.image} alt={hero.data.title} />
</section>
);
}
```
### Admin Panel Integration
```typescript
import React from 'react';
import { ContentEditor } from 'resolvo-cms/react';
function AdminPanel({ client }) {
return (
<div className="admin-panel">
<h1>Content Management</h1>
<ContentEditor
client={client}
schemaId="hero-section"
onSave={(content) => {
console.log('Content saved:', content);
// Show success notification
}}
onPublish={(content) => {
console.log('Content published:', content);
// Show publish notification
}}
/>
</div>
);
}
```
### Real-time Updates
```typescript
import { useContentSubscription } from 'resolvo-cms/react';
function LivePreview({ client, schemaId }) {
const { messages, lastMessage, isConnected } = useContentSubscription(client, schemaId);
return (
<div className="live-preview">
<div className="connection-status">
{isConnected ? '๐ข Connected' : '๐ด Disconnected'}
</div>
{lastMessage && (
<div className="last-update">
Last update: {lastMessage.timestamp.toLocaleTimeString()}
</div>
)}
<div className="update-log">
{messages.map((msg, index) => (
<div key={index} className="update-item">
{msg.type}: {msg.data.id}
</div>
))}
</div>
</div>
);
}
```
## Performance Monitoring
The package includes built-in performance monitoring to track API calls, cache performance, and overall system health.
### Basic Usage
```typescript
import { performanceMonitor, measureAsync } from 'resolvo-cms';
// Monitor a specific operation
const result = await measureAsync('getContent', () =>
client.getContent('content-id')
);
// Get performance statistics
const stats = performanceMonitor.getStats();
console.log('Average response time:', stats.averageDuration);
console.log('Success rate:', stats.successRate);
// Get stats for specific operation
const contentStats = performanceMonitor.getOperationStats('getContent');
console.log('Content fetch performance:', contentStats);
```
### Performance Metrics
- **Response Times**: Track API call durations
- **Success Rates**: Monitor operation success/failure rates
- **Cache Hit Rates**: Measure cache effectiveness
- **Connection Health**: Monitor WebSocket connection stability
- **Memory Usage**: Track memory consumption and cleanup
## Error Handling
The package includes comprehensive error handling with:
- **Error Boundaries**: React error boundaries for graceful error handling
- **Retry Mechanisms**: Automatic retry with exponential backoff
- **Connection Recovery**: Automatic WebSocket reconnection
- **Request Queuing**: Queue requests during connection issues
- **Validation Errors**: Detailed validation error messages
### Error Boundary Usage
```typescript
import { ErrorBoundary } from 'resolvo-cms/react';
function App() {
return (
<ErrorBoundary
fallback={<div>Something went wrong. Please try again.</div>}
onError={(error, errorInfo) => {
console.error('CMS Error:', error, errorInfo);
// Send to error reporting service
}}
>
<ContentEditor client={client} schemaId="hero-section" />
</ErrorBoundary>
);
}
```
## Backend Integration
This package requires a Resolvo API backend with CMS endpoints. The backend should implement:
- Schema management endpoints (`/cms/schemas`)
- Content management endpoints (`/cms/content`)
- Public content endpoints (`/cms/public/content`)
- WebSocket support for real-time updates
- Authentication middleware
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request
## License
MIT License - see LICENSE file for details.