@bernierllc/content-storage
v1.6.0
Published
Universal content storage engine with multiple backend adapters, versioning, and content lifecycle management
Readme
@bernierllc/content-storage
Universal content storage engine with multiple backend adapters, versioning, and content lifecycle management.
Installation
npm install @bernierllc/content-storageUsage
Basic Setup
import { StorageManager, MemoryStorageAdapter } from '@bernierllc/content-storage';
// Create and configure storage manager
const manager = new StorageManager({
enableVersioning: true,
enableRevisions: true,
maxVersions: 10
});
// Register storage adapter
const memoryAdapter = new MemoryStorageAdapter();
await memoryAdapter.connect();
manager.registerAdapter(memoryAdapter);
// Create content
const content = await manager.create({
type: 'post',
title: 'My First Post',
content: 'This is the content of my first post.',
author: 'john-doe',
tags: ['javascript', 'tutorial'],
categories: ['programming']
});
console.log('Created content:', content.id);Content Operations
// Read content
const retrieved = await manager.read(content.id);
// Update content
const updated = await manager.update(content.id, {
title: 'My Updated Post',
content: 'This is the updated content.'
});
// Delete content
const deleted = await manager.delete(content.id);
// Check if content exists
const exists = await manager.exists(content.id);Querying Content
// Query by type
const posts = await manager.query({ type: 'post' });
// Query by status
const published = await manager.query({
status: ContentStatus.PUBLISHED
});
// Search with text
const searchResults = await manager.query({
search: 'javascript tutorial'
});
// Complex query with filters
const results = await manager.query({
type: 'post',
status: [ContentStatus.PUBLISHED, ContentStatus.SCHEDULED],
tags: ['javascript'],
dateRange: {
start: new Date('2025-01-01'),
end: new Date('2025-12-31'),
field: 'publishedAt'
},
sortBy: 'createdAt',
sortOrder: 'desc',
limit: 10,
offset: 0
});
console.log(`Found ${results.total} items:`, results.items);Version Management
// Get all versions of content
const versions = await manager.getVersions(content.id);
// Get specific version
const version = await manager.getVersion(content.id, 1);
// Revert to previous version
const reverted = await manager.revertToVersion(content.id, 1);Bulk Operations
// Bulk create
const items = [
{ type: 'post', title: 'Post 1', content: 'Content 1', author: 'author1' },
{ type: 'post', title: 'Post 2', content: 'Content 2', author: 'author2' },
{ type: 'post', title: 'Post 3', content: 'Content 3', author: 'author3' }
];
const created = await manager.bulkCreate(items);
// Bulk update
const updates = [
{ id: created[0].id, updates: { title: 'Updated Post 1' } },
{ id: created[1].id, updates: { title: 'Updated Post 2' } }
];
const updated = await manager.bulkUpdate(updates);
// Bulk delete
const ids = created.map(item => item.id);
const results = await manager.bulkDelete(ids);Content Validation
import { ValidationEngine, createBasicContentSchema } from '@bernierllc/content-storage';
const validator = new ValidationEngine();
// Register a basic schema
const basicSchema = createBasicContentSchema();
validator.registerSchema(basicSchema);
// Create custom schema
const blogSchema = {
type: 'blog-post',
fields: {
title: {
type: FieldType.STRING,
required: true,
min: 5,
max: 100
},
content: {
type: FieldType.TEXT,
required: true,
min: 50
},
excerpt: {
type: FieldType.TEXT,
max: 200
},
slug: {
type: FieldType.STRING,
format: 'slug'
},
author: {
type: FieldType.EMAIL,
format: 'email',
required: true
},
publishedAt: {
type: FieldType.DATE
}
},
required: ['title', 'content', 'author']
};
validator.registerSchema(blogSchema);
// Validate content
const content = {
type: 'blog-post',
title: 'My Blog Post',
content: 'This is a comprehensive blog post about JavaScript...',
author: '[email protected]',
slug: 'my-blog-post'
};
const result = await validator.validateContent(content);
if (!result.isValid) {
console.log('Validation errors:', result.errors);
console.log('Validation warnings:', result.warnings);
}Event System
import { StorageEventType } from '@bernierllc/content-storage';
// Listen for content events
manager.on(StorageEventType.CONTENT_CREATED, (event) => {
console.log('Content created:', event.contentId);
});
manager.on(StorageEventType.CONTENT_UPDATED, (event) => {
console.log('Content updated:', event.contentId);
});
manager.on(StorageEventType.CONTENT_DELETED, (event) => {
console.log('Content deleted:', event.contentId);
});Health Monitoring
// Check health of all adapters
const healthStatuses = await manager.healthCheck();
healthStatuses.forEach(status => {
console.log(`Adapter health: ${status.status}`);
if (status.error) {
console.error('Health check error:', status.error);
}
});
// Check specific adapter
const memoryHealth = await manager.healthCheck('memory');
console.log('Memory adapter status:', memoryHealth[0].status);Custom Storage Adapters
import { StorageAdapter, StorageType, StorageCapability } from '@bernierllc/content-storage';
class CustomStorageAdapter implements StorageAdapter {
public readonly id = 'custom';
public readonly name = 'Custom Storage';
public readonly type = StorageType.DATABASE;
public readonly capabilities = [
StorageCapability.CREATE,
StorageCapability.READ,
StorageCapability.UPDATE,
StorageCapability.DELETE,
StorageCapability.QUERY
];
async isConnected(): Promise<boolean> {
// Implementation
return true;
}
async connect(): Promise<void> {
// Implementation
}
async disconnect(): Promise<void> {
// Implementation
}
async healthCheck(): Promise<HealthStatus> {
// Implementation
return {
status: 'healthy',
lastCheck: new Date()
};
}
// Implement required methods...
async create(content: Partial<ContentItem>): Promise<ContentItem> {
// Implementation
}
async read(id: string): Promise<ContentItem | null> {
// Implementation
}
// ... other required methods
}
// Register custom adapter
const customAdapter = new CustomStorageAdapter();
await customAdapter.connect();
manager.registerAdapter(customAdapter);API Reference
StorageManager
Main orchestrator class for content storage operations.
Constructor
new StorageManager(config?: Partial<StorageConfig>)
Methods
registerAdapter(adapter: StorageAdapter): voidgetAdapter(id?: string): StorageAdaptercreate(content: Partial<ContentItem>, adapterId?: string): Promise<ContentItem>read(id: string, adapterId?: string): Promise<ContentItem | null>update(id: string, updates: Partial<ContentItem>, adapterId?: string): Promise<ContentItem>delete(id: string, adapterId?: string): Promise<boolean>query(query: ContentQuery, adapterId?: string): Promise<ContentQueryResult>bulkCreate(items: Partial<ContentItem>[], adapterId?: string): Promise<ContentItem[]>getVersions(contentId: string, adapterId?: string): Promise<ContentVersion[]>healthCheck(adapterId?: string): Promise<HealthStatus[]>
MemoryStorageAdapter
In-memory storage adapter for development and testing.
Features
- Full CRUD operations
- Content querying with filtering, sorting, pagination
- Version management
- Revision tracking
- Bulk operations
- Content archiving and trash management
ValidationEngine
Content validation system with schema support.
Methods
registerSchema(schema: ContentSchema): voidvalidateContent(content: Partial<ContentItem>): Promise<ValidationResult>registerValidator(name: string, validator: ContentValidator): void
Configuration
interface StorageConfig {
defaultAdapter?: string;
enableVersioning: boolean;
enableRevisions: boolean;
maxVersions: number;
autoCleanup: boolean;
cleanupInterval: number;
enableCaching: boolean;
cacheSize: number;
cacheTTL: number;
enableCompression: boolean;
compressionThreshold: number;
enableEncryption: boolean;
encryptionKey?: string;
backupEnabled: boolean;
backupInterval: number;
retentionPolicy?: RetentionPolicy;
}Types
ContentItem
Core content structure with metadata, versioning, and lifecycle information.
ContentQuery
Flexible query interface supporting filtering, searching, sorting, and pagination.
StorageAdapter
Interface for implementing custom storage backends.
ContentSchema
Schema definition for content validation.
See Also
- @bernierllc/retry-policy - For implementing retry logic in custom adapters
- @bernierllc/crypto-utils - For content encryption features
License
Copyright (c) 2025 Bernier LLC. All rights reserved.
