doc-changes-5-7 #4
391
.claude/development-guidelines.md
Normal file
391
.claude/development-guidelines.md
Normal file
@ -0,0 +1,391 @@
|
||||
# DebrosFramework Development Guidelines
|
||||
|
||||
## Code Style and Standards
|
||||
|
||||
### TypeScript Configuration
|
||||
- **Strict Mode**: Always use strict TypeScript configuration
|
||||
- **Decorators**: Enable `experimentalDecorators` and `emitDecoratorMetadata`
|
||||
- **Target**: ES2020 for modern JavaScript features
|
||||
- **Module System**: ES modules with CommonJS interop
|
||||
|
||||
### Code Formatting
|
||||
- **Prettier**: Use Prettier for consistent code formatting
|
||||
- **ESLint**: Follow ESLint rules for code quality
|
||||
- **Indentation**: 2 spaces for all files
|
||||
- **Line Length**: Max 120 characters per line
|
||||
- **Semicolons**: Always use semicolons
|
||||
- **Quotes**: Single quotes for strings, double quotes for JSX
|
||||
|
||||
### Naming Conventions
|
||||
- **Classes**: PascalCase (e.g., `UserModel`, `QueryBuilder`)
|
||||
- **Functions/Methods**: camelCase (e.g., `createUser`, `findById`)
|
||||
- **Variables**: camelCase (e.g., `userId`, `queryResult`)
|
||||
- **Constants**: UPPER_SNAKE_CASE (e.g., `DEFAULT_CACHE_SIZE`)
|
||||
- **Files**: PascalCase for classes, camelCase for utilities
|
||||
- **Interfaces**: PascalCase with descriptive names (e.g., `ModelConfig`)
|
||||
|
||||
## Framework Architecture Patterns
|
||||
|
||||
### Model System
|
||||
```typescript
|
||||
// Always extend BaseModel for data models
|
||||
@Model({
|
||||
scope: 'user' | 'global',
|
||||
type: 'docstore',
|
||||
sharding: { strategy: 'hash', count: 4, key: 'fieldName' }
|
||||
})
|
||||
export class ModelName extends BaseModel {
|
||||
@Field({ type: 'string', required: true })
|
||||
propertyName: string;
|
||||
|
||||
@BelongsTo(() => RelatedModel, 'foreignKey')
|
||||
relation: RelatedModel;
|
||||
}
|
||||
```
|
||||
|
||||
### Query Patterns
|
||||
```typescript
|
||||
// Use chainable query builder pattern
|
||||
const results = await Model.query()
|
||||
.where('field', 'operator', value)
|
||||
.with(['relationship1', 'relationship2'])
|
||||
.orderBy('field', 'direction')
|
||||
.limit(count)
|
||||
.find();
|
||||
|
||||
// Prefer specific methods over generic ones
|
||||
const user = await User.findById(id); // Good
|
||||
const user = await User.query().where('id', id).findOne(); // Less preferred
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
```typescript
|
||||
// Always use try-catch for async operations
|
||||
try {
|
||||
const result = await someAsyncOperation();
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Operation failed:', error);
|
||||
throw new DebrosFrameworkError('Descriptive error message', { originalError: error });
|
||||
}
|
||||
|
||||
// Validate inputs early
|
||||
if (!userId || typeof userId !== 'string') {
|
||||
throw new ValidationError('User ID must be a non-empty string');
|
||||
}
|
||||
```
|
||||
|
||||
### Service Layer Pattern
|
||||
```typescript
|
||||
// Encapsulate business logic in service classes
|
||||
export class UserService {
|
||||
async createUser(userData: CreateUserData): Promise<User> {
|
||||
// Validation
|
||||
await this.validateUserData(userData);
|
||||
|
||||
// Business logic
|
||||
const user = await User.create(userData);
|
||||
|
||||
// Post-processing
|
||||
await this.sendWelcomeEmail(user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
private async validateUserData(data: CreateUserData): Promise<void> {
|
||||
// Validation logic
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Standards
|
||||
|
||||
### Unit Tests
|
||||
- **Jest**: Use Jest for all unit testing
|
||||
- **Mocking**: Mock external dependencies (OrbitDB, IPFS)
|
||||
- **Coverage**: Aim for >90% code coverage
|
||||
- **Structure**: One test file per source file
|
||||
- **Naming**: `*.test.ts` for test files
|
||||
|
||||
```typescript
|
||||
describe('ModelName', () => {
|
||||
let model: ModelName;
|
||||
|
||||
beforeEach(() => {
|
||||
model = new ModelName();
|
||||
});
|
||||
|
||||
describe('methodName', () => {
|
||||
it('should handle normal case', async () => {
|
||||
// Arrange
|
||||
const input = 'test value';
|
||||
|
||||
// Act
|
||||
const result = await model.methodName(input);
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result.property).toBe('expected value');
|
||||
});
|
||||
|
||||
it('should throw error for invalid input', async () => {
|
||||
// Arrange & Act & Assert
|
||||
await expect(model.methodName(null)).rejects.toThrow('Expected error message');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
- **Docker**: Use Docker for real integration tests
|
||||
- **Scenarios**: Test complete user workflows
|
||||
- **Data**: Use realistic test data
|
||||
- **Cleanup**: Always clean up test data
|
||||
|
||||
## Performance Guidelines
|
||||
|
||||
### Query Optimization
|
||||
```typescript
|
||||
// Use selective field loading when possible
|
||||
const users = await User.query().select(['id', 'username']).find();
|
||||
|
||||
// Prefer eager loading for predictable relationships
|
||||
const posts = await Post.query().with(['author', 'comments']).find();
|
||||
|
||||
// Use caching for expensive queries
|
||||
const popularPosts = await Post.query()
|
||||
.where('likeCount', '>', 100)
|
||||
.cache(300) // Cache for 5 minutes
|
||||
.find();
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
- **Lazy Loading**: Use lazy loading for large datasets
|
||||
- **Pagination**: Always use pagination for large result sets
|
||||
- **Cache Limits**: Set appropriate cache size limits
|
||||
- **Cleanup**: Clean up resources in finally blocks
|
||||
|
||||
### Database Design
|
||||
- **Sharding**: Design effective sharding strategies
|
||||
- **Indexing**: Use indexes for frequently queried fields
|
||||
- **Relationships**: Avoid deep relationship chains
|
||||
- **Data Types**: Use appropriate data types for storage efficiency
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Input Validation
|
||||
```typescript
|
||||
// Always validate and sanitize inputs
|
||||
@Field({
|
||||
type: 'string',
|
||||
required: true,
|
||||
validate: (value: string) => value.length >= 3 && value.length <= 50,
|
||||
transform: (value: string) => value.trim().toLowerCase()
|
||||
})
|
||||
username: string;
|
||||
```
|
||||
|
||||
### Access Control
|
||||
- **User Scoping**: Use user-scoped models for private data
|
||||
- **Validation**: Validate user permissions before operations
|
||||
- **Sanitization**: Sanitize all user inputs
|
||||
- **Encryption**: Use encryption for sensitive data
|
||||
|
||||
### Error Messages
|
||||
- **Security**: Don't expose internal system details in error messages
|
||||
- **Logging**: Log security-relevant events
|
||||
- **Validation**: Provide clear validation error messages
|
||||
|
||||
## Documentation Standards
|
||||
|
||||
### Code Documentation
|
||||
```typescript
|
||||
/**
|
||||
* Creates a new user with the provided data.
|
||||
*
|
||||
* @param userData - The user data to create
|
||||
* @param options - Additional creation options
|
||||
* @returns Promise resolving to the created user
|
||||
* @throws ValidationError if user data is invalid
|
||||
* @throws DuplicateError if username or email already exists
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const user = await userService.createUser({
|
||||
* username: 'alice',
|
||||
* email: 'alice@example.com'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
async createUser(userData: CreateUserData, options?: CreateOptions): Promise<User> {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
### README Updates
|
||||
- Keep README.md up to date with latest features
|
||||
- Include practical examples
|
||||
- Document breaking changes
|
||||
- Provide migration guides
|
||||
|
||||
### API Documentation
|
||||
- Document all public APIs
|
||||
- Include parameter types and return types
|
||||
- Provide usage examples
|
||||
- Document error conditions
|
||||
|
||||
## Common Patterns and Anti-Patterns
|
||||
|
||||
### ✅ Good Patterns
|
||||
|
||||
#### Model Definition
|
||||
```typescript
|
||||
@Model({
|
||||
scope: 'user',
|
||||
type: 'docstore',
|
||||
sharding: { strategy: 'hash', count: 4, key: 'userId' }
|
||||
})
|
||||
export class Post extends BaseModel {
|
||||
@Field({ type: 'string', required: true, maxLength: 200 })
|
||||
title: string;
|
||||
|
||||
@Field({ type: 'string', required: true })
|
||||
content: string;
|
||||
|
||||
@BeforeCreate()
|
||||
setDefaults() {
|
||||
this.createdAt = Date.now();
|
||||
this.updatedAt = Date.now();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Service Methods
|
||||
```typescript
|
||||
async createPost(authorId: string, postData: CreatePostData): Promise<Post> {
|
||||
// Validate input
|
||||
if (!authorId) throw new ValidationError('Author ID is required');
|
||||
|
||||
// Check permissions
|
||||
const author = await User.findById(authorId);
|
||||
if (!author) throw new NotFoundError('Author not found');
|
||||
|
||||
// Create post
|
||||
const post = await Post.create({
|
||||
...postData,
|
||||
authorId,
|
||||
});
|
||||
|
||||
// Post-processing
|
||||
await this.notifyFollowers(author, post);
|
||||
|
||||
return post;
|
||||
}
|
||||
```
|
||||
|
||||
### ❌ Anti-Patterns
|
||||
|
||||
#### Avoid Direct Database Access
|
||||
```typescript
|
||||
// Bad: Direct database manipulation
|
||||
const db = await orbitdb.open('posts');
|
||||
await db.put('key', data);
|
||||
|
||||
// Good: Use model methods
|
||||
const post = await Post.create(data);
|
||||
```
|
||||
|
||||
#### Avoid Synchronous Operations
|
||||
```typescript
|
||||
// Bad: Synchronous file operations
|
||||
const data = fs.readFileSync('file.json');
|
||||
|
||||
// Good: Async operations
|
||||
const data = await fs.promises.readFile('file.json');
|
||||
```
|
||||
|
||||
#### Avoid Deep Relationship Chains
|
||||
```typescript
|
||||
// Bad: Deep relationship loading
|
||||
const posts = await Post.query()
|
||||
.with(['author.profile.settings.preferences'])
|
||||
.find();
|
||||
|
||||
// Good: Load only what you need
|
||||
const posts = await Post.query()
|
||||
.with(['author'])
|
||||
.find();
|
||||
```
|
||||
|
||||
## Migration Guidelines
|
||||
|
||||
### Schema Changes
|
||||
```typescript
|
||||
// Create migration for schema changes
|
||||
const migration = createMigration('add_user_avatar', '1.1.0')
|
||||
.addField('User', 'avatarUrl', {
|
||||
type: 'string',
|
||||
required: false
|
||||
})
|
||||
.transformData('User', (user) => ({
|
||||
...user,
|
||||
avatarUrl: user.avatarUrl || null
|
||||
}))
|
||||
.build();
|
||||
```
|
||||
|
||||
### Backwards Compatibility
|
||||
- Always maintain backwards compatibility in minor versions
|
||||
- Deprecate features before removing them
|
||||
- Provide migration paths for breaking changes
|
||||
- Document all changes in CHANGELOG.md
|
||||
|
||||
## Deployment Considerations
|
||||
|
||||
### Environment Configuration
|
||||
- Use environment variables for configuration
|
||||
- Provide default configurations for development
|
||||
- Validate configuration on startup
|
||||
- Document required environment variables
|
||||
|
||||
### Production Readiness
|
||||
- Enable production optimizations
|
||||
- Configure appropriate cache sizes
|
||||
- Set up monitoring and logging
|
||||
- Implement health checks
|
||||
|
||||
### Performance Monitoring
|
||||
- Monitor query performance
|
||||
- Track cache hit rates
|
||||
- Monitor memory usage
|
||||
- Set up alerts for errors
|
||||
|
||||
## Contributing Guidelines
|
||||
|
||||
### Pull Request Process
|
||||
1. Fork the repository
|
||||
2. Create feature branch from main
|
||||
3. Implement changes with tests
|
||||
4. Update documentation
|
||||
5. Submit pull request with description
|
||||
|
||||
### Code Review Checklist
|
||||
- [ ] Code follows style guidelines
|
||||
- [ ] Tests are included and passing
|
||||
- [ ] Documentation is updated
|
||||
- [ ] No breaking changes (or properly documented)
|
||||
- [ ] Performance implications considered
|
||||
- [ ] Security implications reviewed
|
||||
|
||||
### Commit Message Format
|
||||
```
|
||||
type(scope): description
|
||||
|
||||
body (optional)
|
||||
|
||||
footer (optional)
|
||||
```
|
||||
|
||||
Types: feat, fix, docs, style, refactor, test, chore
|
||||
|
||||
These guidelines ensure consistent, maintainable, and high-quality code throughout the DebrosFramework project.
|
249
.claude/project-overview.md
Normal file
249
.claude/project-overview.md
Normal file
@ -0,0 +1,249 @@
|
||||
# DebrosFramework Project Overview
|
||||
|
||||
## Project Identity
|
||||
**DebrosFramework** is a powerful Node.js framework that provides an ORM-like abstraction over OrbitDB and IPFS, making it easy to build scalable decentralized applications.
|
||||
|
||||
- **Package Name**: `@debros/network`
|
||||
- **Version**: 0.5.1-beta (Active Development)
|
||||
- **License**: GNU GPL v3.0
|
||||
- **Language**: TypeScript
|
||||
- **Framework Type**: Decentralized Application Framework
|
||||
|
||||
## What This Project Does
|
||||
|
||||
DebrosFramework simplifies the development of decentralized applications by providing:
|
||||
|
||||
### Core Capabilities
|
||||
- **Model-based Abstraction**: Define data models using decorators and TypeScript classes
|
||||
- **Automatic Database Management**: Handle user-scoped and global databases automatically
|
||||
- **Smart Sharding**: Distribute data across multiple databases for scalability
|
||||
- **Advanced Query System**: Rich query capabilities with relationship loading and caching
|
||||
- **Automatic Features**: Built-in pinning strategies and PubSub event publishing
|
||||
- **Migration System**: Schema evolution and data transformation capabilities
|
||||
- **Type Safety**: Full TypeScript support with strong typing throughout
|
||||
|
||||
### Key Features
|
||||
1. **🏗️ Model-Driven Development**: Familiar decorator patterns for data models
|
||||
2. **🔍 Powerful Query System**: Complex queries with relationship loading
|
||||
3. **🚀 Automatic Scaling**: Handle millions of users with automatic sharding
|
||||
4. **🔄 Schema Evolution**: Safe data structure migrations
|
||||
5. **🔗 Rich Relationships**: Complex relationships between models
|
||||
6. **⚡ Performance Features**: Query caching, eager loading, optimized pagination
|
||||
7. **🎯 Model Hooks**: Lifecycle hooks for business logic
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The framework is built around several core components:
|
||||
|
||||
1. **Models & Decorators**: Define data structure and behavior
|
||||
2. **Database Manager**: Handles database creation and management
|
||||
3. **Shard Manager**: Distributes data across multiple databases
|
||||
4. **Query System**: Processes queries with optimization and caching
|
||||
5. **Relationship Manager**: Handles complex relationships between models
|
||||
6. **Migration System**: Manages schema evolution over time
|
||||
7. **Automatic Features**: Pinning, PubSub, and performance optimization
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Core Dependencies
|
||||
- **OrbitDB**: Distributed peer-to-peer database on IPFS
|
||||
- **IPFS/Helia**: Distributed file system for data storage
|
||||
- **libp2p**: Peer-to-peer networking stack
|
||||
- **TypeScript**: Strong typing and modern JavaScript features
|
||||
|
||||
### Key Libraries
|
||||
- `@orbitdb/core`: Core OrbitDB functionality
|
||||
- `@helia/unixfs`: IPFS file system operations
|
||||
- `@libp2p/*`: Various libp2p modules for networking
|
||||
- `winston`: Logging
|
||||
- `node-cache`: In-memory caching
|
||||
- `express`: HTTP server for integration tests
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/framework/
|
||||
├── core/ # Core framework components
|
||||
│ ├── ConfigManager.ts
|
||||
│ ├── DatabaseManager.ts
|
||||
│ └── ModelRegistry.ts
|
||||
├── models/ # Model system and decorators
|
||||
│ ├── BaseModel.ts
|
||||
│ └── decorators/
|
||||
├── query/ # Query builder and execution
|
||||
│ ├── QueryBuilder.ts
|
||||
│ ├── QueryExecutor.ts
|
||||
│ ├── QueryOptimizer.ts
|
||||
│ └── QueryCache.ts
|
||||
├── relationships/ # Relationship management
|
||||
│ ├── RelationshipManager.ts
|
||||
│ ├── LazyLoader.ts
|
||||
│ └── RelationshipCache.ts
|
||||
├── sharding/ # Data sharding logic
|
||||
│ └── ShardManager.ts
|
||||
├── migrations/ # Schema migration system
|
||||
│ ├── MigrationManager.ts
|
||||
│ └── MigrationBuilder.ts
|
||||
├── pinning/ # Automatic pinning features
|
||||
│ └── PinningManager.ts
|
||||
├── pubsub/ # Event publishing system
|
||||
│ └── PubSubManager.ts
|
||||
├── services/ # External service integrations
|
||||
│ ├── OrbitDBService.ts
|
||||
│ ├── IPFSService.ts
|
||||
│ └── RealOrbitDBService.ts
|
||||
└── types/ # TypeScript type definitions
|
||||
├── framework.ts
|
||||
├── models.ts
|
||||
└── queries.ts
|
||||
```
|
||||
|
||||
## Development Status
|
||||
|
||||
**Current State**: Beta (v0.5.1-beta) - Active Development
|
||||
|
||||
### What's Stable
|
||||
- ✅ Core model system with decorators
|
||||
- ✅ Basic CRUD operations
|
||||
- ✅ Query builder and execution
|
||||
- ✅ Relationship management
|
||||
- ✅ Database management and sharding
|
||||
- ✅ Migration system foundation
|
||||
|
||||
### What's In Development
|
||||
- 🚧 Advanced query optimization
|
||||
- 🚧 Performance optimization features
|
||||
- 🚧 Production-ready configurations
|
||||
- 🚧 Extended relationship types
|
||||
- 🚧 Enhanced error handling
|
||||
|
||||
### Testing
|
||||
- **Unit Tests**: Comprehensive test suite using Jest
|
||||
- **Integration Tests**: Docker-based real-world scenarios
|
||||
- **Blog Scenario**: Complete blogging platform test case
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Model Scoping
|
||||
- **Global Models**: Shared across all users (e.g., User profiles)
|
||||
- **User Models**: Each user has their own database instance (e.g., Posts, Comments)
|
||||
|
||||
### Sharding Strategies
|
||||
- **Hash Sharding**: Distribute data based on key hashing
|
||||
- **Range Sharding**: Distribute data based on value ranges
|
||||
- **User Sharding**: Dedicated shards per user or user group
|
||||
|
||||
### Query System
|
||||
- **Chainable API**: Fluent interface for building queries
|
||||
- **Type Safety**: Full TypeScript support with auto-completion
|
||||
- **Relationship Loading**: Eager and lazy loading strategies
|
||||
- **Caching**: Intelligent query result caching
|
||||
|
||||
### Relationships
|
||||
- **BelongsTo**: Many-to-one relationships
|
||||
- **HasMany**: One-to-many relationships
|
||||
- **HasOne**: One-to-one relationships
|
||||
- **ManyToMany**: Many-to-many relationships (with through tables)
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### 1. Social Platforms
|
||||
- User profiles and authentication
|
||||
- Posts, comments, and reactions
|
||||
- Friend networks and messaging
|
||||
- Activity feeds and notifications
|
||||
|
||||
### 2. Content Management
|
||||
- Blogs and publishing platforms
|
||||
- Document management systems
|
||||
- Media galleries and collections
|
||||
- Version control for content
|
||||
|
||||
### 3. Collaborative Applications
|
||||
- Real-time document editing
|
||||
- Project management tools
|
||||
- Team collaboration platforms
|
||||
- Knowledge bases and wikis
|
||||
|
||||
### 4. Marketplace Applications
|
||||
- Product catalogs and inventory
|
||||
- User reviews and ratings
|
||||
- Order management systems
|
||||
- Payment and transaction records
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Prerequisites
|
||||
- Node.js 18.0 or higher
|
||||
- TypeScript knowledge
|
||||
- Basic understanding of IPFS and OrbitDB concepts
|
||||
- Docker (for integration tests)
|
||||
|
||||
### Build Process
|
||||
```bash
|
||||
npm run build # Compile TypeScript
|
||||
npm run dev # Development with watch mode
|
||||
npm run lint # ESLint code checking
|
||||
npm run format # Prettier code formatting
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
npm run test:unit # Fast unit tests with mocks
|
||||
npm run test:real # Full integration tests with Docker
|
||||
npm run test:blog-integration # Blog scenario integration tests
|
||||
```
|
||||
|
||||
### Key Development Principles
|
||||
1. **Type Safety First**: Everything is strongly typed
|
||||
2. **Decorator-Based**: Use decorators for configuration
|
||||
3. **Async/Await**: All operations are promise-based
|
||||
4. **Error Handling**: Comprehensive error management
|
||||
5. **Performance**: Built-in optimization and caching
|
||||
6. **Scalability**: Designed for distributed systems
|
||||
|
||||
## API Patterns
|
||||
|
||||
### Model Definition
|
||||
```typescript
|
||||
@Model({
|
||||
scope: 'user',
|
||||
type: 'docstore',
|
||||
sharding: { strategy: 'hash', count: 4, key: 'userId' }
|
||||
})
|
||||
class Post extends BaseModel {
|
||||
@Field({ type: 'string', required: true })
|
||||
title: string;
|
||||
|
||||
@BelongsTo(() => User, 'userId')
|
||||
user: User;
|
||||
}
|
||||
```
|
||||
|
||||
### Query Operations
|
||||
```typescript
|
||||
const posts = await Post.query()
|
||||
.where('isPublished', true)
|
||||
.where('createdAt', '>', Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||||
.with(['user', 'comments'])
|
||||
.orderBy('likeCount', 'desc')
|
||||
.limit(20)
|
||||
.find();
|
||||
```
|
||||
|
||||
### Lifecycle Hooks
|
||||
```typescript
|
||||
class User extends BaseModel {
|
||||
@BeforeCreate()
|
||||
setupNewUser() {
|
||||
this.registeredAt = Date.now();
|
||||
}
|
||||
|
||||
@AfterCreate()
|
||||
async sendWelcomeEmail() {
|
||||
// Business logic after creation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This framework makes building decentralized applications feel like traditional web development while providing the benefits of distributed, peer-to-peer systems.
|
607
.claude/technical-reference.md
Normal file
607
.claude/technical-reference.md
Normal file
@ -0,0 +1,607 @@
|
||||
# DebrosFramework Technical Reference
|
||||
|
||||
## Core Architecture Components
|
||||
|
||||
### DebrosFramework Main Class
|
||||
**Location**: `src/framework/DebrosFramework.ts`
|
||||
|
||||
The main framework class that orchestrates all components:
|
||||
|
||||
```typescript
|
||||
export class DebrosFramework {
|
||||
// Core services
|
||||
private orbitDBService: FrameworkOrbitDBService;
|
||||
private ipfsService: FrameworkIPFSService;
|
||||
|
||||
// Framework components
|
||||
private databaseManager: DatabaseManager;
|
||||
private shardManager: ShardManager;
|
||||
private queryCache: QueryCache;
|
||||
private relationshipManager: RelationshipManager;
|
||||
private pinningManager: PinningManager;
|
||||
private pubsubManager: PubSubManager;
|
||||
private migrationManager: MigrationManager;
|
||||
|
||||
// Lifecycle methods
|
||||
async initialize(orbitDBService?, ipfsService?, config?): Promise<void>
|
||||
async start(): Promise<void>
|
||||
async stop(): Promise<void>
|
||||
getStatus(): FrameworkStatus
|
||||
getMetrics(): FrameworkMetrics
|
||||
}
|
||||
```
|
||||
|
||||
### BaseModel Class
|
||||
**Location**: `src/framework/models/BaseModel.ts`
|
||||
|
||||
Abstract base class for all data models:
|
||||
|
||||
```typescript
|
||||
export abstract class BaseModel {
|
||||
// Instance properties
|
||||
public id: string;
|
||||
public _loadedRelations: Map<string, any>;
|
||||
protected _isDirty: boolean;
|
||||
protected _isNew: boolean;
|
||||
|
||||
// Static configuration
|
||||
static modelName: string;
|
||||
static storeType: StoreType;
|
||||
static scope: 'user' | 'global';
|
||||
static sharding?: ShardingConfig;
|
||||
static fields: Map<string, FieldConfig>;
|
||||
static relationships: Map<string, RelationshipConfig>;
|
||||
|
||||
// CRUD operations
|
||||
async save(): Promise<this>
|
||||
static async create<T>(data: any): Promise<T>
|
||||
static async findById<T>(id: string): Promise<T | null>
|
||||
static query<T>(): QueryBuilder<T>
|
||||
async delete(): Promise<void>
|
||||
|
||||
// Lifecycle hooks
|
||||
async beforeCreate(): Promise<void>
|
||||
async afterCreate(): Promise<void>
|
||||
async beforeUpdate(): Promise<void>
|
||||
async afterUpdate(): Promise<void>
|
||||
async beforeDelete(): Promise<void>
|
||||
async afterDelete(): Promise<void>
|
||||
}
|
||||
```
|
||||
|
||||
## Decorator System
|
||||
|
||||
### @Model Decorator
|
||||
**Location**: `src/framework/models/decorators/Model.ts`
|
||||
|
||||
Configures model behavior and database storage:
|
||||
|
||||
```typescript
|
||||
interface ModelConfig {
|
||||
scope: 'user' | 'global'; // Database scope
|
||||
type: StoreType; // OrbitDB store type
|
||||
sharding?: ShardingConfig; // Data distribution strategy
|
||||
pinning?: PinningConfig; // Automatic pinning configuration
|
||||
pubsub?: PubSubConfig; // Event publishing configuration
|
||||
validation?: ValidationConfig; // Model-level validation
|
||||
}
|
||||
|
||||
@Model({
|
||||
scope: 'user',
|
||||
type: 'docstore',
|
||||
sharding: { strategy: 'hash', count: 4, key: 'userId' }
|
||||
})
|
||||
```
|
||||
|
||||
### @Field Decorator
|
||||
**Location**: `src/framework/models/decorators/Field.ts`
|
||||
|
||||
Defines field properties and validation:
|
||||
|
||||
```typescript
|
||||
interface FieldConfig {
|
||||
type: FieldType; // Data type
|
||||
required?: boolean; // Required field
|
||||
unique?: boolean; // Unique constraint
|
||||
default?: any | (() => any); // Default value
|
||||
validate?: (value: any) => boolean; // Custom validation
|
||||
transform?: (value: any) => any; // Data transformation
|
||||
serialize?: boolean; // Include in serialization
|
||||
index?: boolean; // Create index for field
|
||||
virtual?: boolean; // Virtual field (not stored)
|
||||
}
|
||||
|
||||
@Field({
|
||||
type: 'string',
|
||||
required: true,
|
||||
unique: true,
|
||||
validate: (value: string) => value.length >= 3,
|
||||
transform: (value: string) => value.trim().toLowerCase()
|
||||
})
|
||||
```
|
||||
|
||||
### Relationship Decorators
|
||||
**Location**: `src/framework/models/decorators/relationships.ts`
|
||||
|
||||
```typescript
|
||||
// Many-to-one relationship
|
||||
@BelongsTo(() => User, 'userId')
|
||||
author: User;
|
||||
|
||||
// One-to-many relationship
|
||||
@HasMany(() => Post, 'authorId')
|
||||
posts: Post[];
|
||||
|
||||
// One-to-one relationship
|
||||
@HasOne(() => Profile, 'userId')
|
||||
profile: Profile;
|
||||
|
||||
// Many-to-many relationship
|
||||
@ManyToMany(() => Tag, 'post_tags', 'tag_id', 'post_id')
|
||||
tags: Tag[];
|
||||
```
|
||||
|
||||
### Lifecycle Hook Decorators
|
||||
**Location**: `src/framework/models/decorators/hooks.ts`
|
||||
|
||||
```typescript
|
||||
@BeforeCreate()
|
||||
setupDefaults() {
|
||||
this.createdAt = Date.now();
|
||||
}
|
||||
|
||||
@AfterCreate()
|
||||
async sendNotification() {
|
||||
await this.notifyUsers();
|
||||
}
|
||||
|
||||
@BeforeUpdate()
|
||||
updateTimestamp() {
|
||||
this.updatedAt = Date.now();
|
||||
}
|
||||
|
||||
@AfterUpdate()
|
||||
async invalidateCache() {
|
||||
await this.clearRelatedCache();
|
||||
}
|
||||
|
||||
@BeforeDelete()
|
||||
async checkPermissions() {
|
||||
if (!this.canDelete()) {
|
||||
throw new Error('Cannot delete this record');
|
||||
}
|
||||
}
|
||||
|
||||
@AfterDelete()
|
||||
async cleanupRelations() {
|
||||
await this.removeRelatedData();
|
||||
}
|
||||
```
|
||||
|
||||
## Query System
|
||||
|
||||
### QueryBuilder Class
|
||||
**Location**: `src/framework/query/QueryBuilder.ts`
|
||||
|
||||
Fluent interface for building queries:
|
||||
|
||||
```typescript
|
||||
export class QueryBuilder<T> {
|
||||
// Filter methods
|
||||
where(field: string, value: any): QueryBuilder<T>
|
||||
where(field: string, operator: string, value: any): QueryBuilder<T>
|
||||
where(callback: (query: QueryBuilder<T>) => void): QueryBuilder<T>
|
||||
orWhere(field: string, value: any): QueryBuilder<T>
|
||||
whereIn(field: string, values: any[]): QueryBuilder<T>
|
||||
whereNotIn(field: string, values: any[]): QueryBuilder<T>
|
||||
whereNull(field: string): QueryBuilder<T>
|
||||
whereNotNull(field: string): QueryBuilder<T>
|
||||
whereLike(field: string, pattern: string): QueryBuilder<T>
|
||||
|
||||
// Relationship methods
|
||||
with(relations: string[]): QueryBuilder<T>
|
||||
withCount(relations: string[]): QueryBuilder<T>
|
||||
|
||||
// Ordering and limiting
|
||||
orderBy(field: string, direction?: 'asc' | 'desc'): QueryBuilder<T>
|
||||
limit(count: number): QueryBuilder<T>
|
||||
offset(count: number): QueryBuilder<T>
|
||||
|
||||
// Field selection
|
||||
select(fields: string[]): QueryBuilder<T>
|
||||
distinct(field?: string): QueryBuilder<T>
|
||||
|
||||
// Caching
|
||||
cache(ttl?: number): QueryBuilder<T>
|
||||
|
||||
// Execution methods
|
||||
find(): Promise<T[]>
|
||||
findOne(): Promise<T | null>
|
||||
first(): Promise<T | null>
|
||||
count(): Promise<number>
|
||||
exists(): Promise<boolean>
|
||||
paginate(page: number, perPage: number): Promise<PaginationResult<T>>
|
||||
|
||||
// Aggregation
|
||||
sum(field: string): Promise<number>
|
||||
avg(field: string): Promise<number>
|
||||
min(field: string): Promise<any>
|
||||
max(field: string): Promise<any>
|
||||
}
|
||||
```
|
||||
|
||||
### Query Operators
|
||||
```typescript
|
||||
type QueryOperator =
|
||||
| 'eq' // Equal to
|
||||
| 'ne' // Not equal to
|
||||
| 'gt' // Greater than
|
||||
| 'gte' // Greater than or equal
|
||||
| 'lt' // Less than
|
||||
| 'lte' // Less than or equal
|
||||
| 'in' // In array
|
||||
| 'not in' // Not in array
|
||||
| 'like' // Pattern matching
|
||||
| 'regex' // Regular expression
|
||||
| 'is null' // Is null
|
||||
| 'is not null' // Is not null
|
||||
| 'includes' // Array includes value
|
||||
| 'includes any'// Array includes any of values
|
||||
| 'includes all'// Array includes all values
|
||||
```
|
||||
|
||||
## Database Management
|
||||
|
||||
### DatabaseManager Class
|
||||
**Location**: `src/framework/core/DatabaseManager.ts`
|
||||
|
||||
Handles database creation and lifecycle:
|
||||
|
||||
```typescript
|
||||
export class DatabaseManager {
|
||||
// Database operations
|
||||
async getGlobalDatabase(modelName: string): Promise<Database>
|
||||
async getUserDatabase(userId: string, modelName: string): Promise<Database>
|
||||
async createDatabase(name: string, type: StoreType, options?: any): Promise<Database>
|
||||
async closeDatabase(name: string): Promise<void>
|
||||
|
||||
// Document operations
|
||||
async getDocument(database: Database, storeType: StoreType, id: string): Promise<any>
|
||||
async putDocument(database: Database, storeType: StoreType, id: string, data: any): Promise<void>
|
||||
async deleteDocument(database: Database, storeType: StoreType, id: string): Promise<void>
|
||||
async queryDocuments(database: Database, storeType: StoreType, query: any): Promise<any[]>
|
||||
|
||||
// Lifecycle
|
||||
async initialize(orbitDBService: FrameworkOrbitDBService): Promise<void>
|
||||
async stop(): Promise<void>
|
||||
}
|
||||
```
|
||||
|
||||
### ShardManager Class
|
||||
**Location**: `src/framework/sharding/ShardManager.ts`
|
||||
|
||||
Handles data distribution across shards:
|
||||
|
||||
```typescript
|
||||
export class ShardManager {
|
||||
// Shard operations
|
||||
getShardForKey(modelName: string, key: string): Shard
|
||||
getShardForRange(modelName: string, value: any): Shard
|
||||
getAllShards(modelName: string): Shard[]
|
||||
|
||||
// Shard management
|
||||
async createShards(modelName: string, config: ShardingConfig): Promise<void>
|
||||
async redistributeData(modelName: string, newShardCount: number): Promise<void>
|
||||
|
||||
// Configuration
|
||||
setShardingConfig(modelName: string, config: ShardingConfig): void
|
||||
getShardingConfig(modelName: string): ShardingConfig | undefined
|
||||
}
|
||||
|
||||
interface ShardingConfig {
|
||||
strategy: 'hash' | 'range' | 'user';
|
||||
count: number;
|
||||
key: string;
|
||||
ranges?: ShardRange[];
|
||||
}
|
||||
|
||||
interface Shard {
|
||||
id: string;
|
||||
database: Database;
|
||||
range?: { min: any; max: any };
|
||||
}
|
||||
```
|
||||
|
||||
## Relationship Management
|
||||
|
||||
### RelationshipManager Class
|
||||
**Location**: `src/framework/relationships/RelationshipManager.ts`
|
||||
|
||||
Handles loading and caching of model relationships:
|
||||
|
||||
```typescript
|
||||
export class RelationshipManager {
|
||||
// Relationship loading
|
||||
async loadRelationship(model: BaseModel, relationshipName: string): Promise<any>
|
||||
async loadRelationships(model: BaseModel, relationshipNames: string[]): Promise<void>
|
||||
async eagerLoadRelationships(models: BaseModel[], relationshipNames: string[]): Promise<void>
|
||||
|
||||
// Relationship operations
|
||||
async attachRelationship(model: BaseModel, relationshipName: string, relatedModel: BaseModel): Promise<void>
|
||||
async detachRelationship(model: BaseModel, relationshipName: string, relatedModel: BaseModel): Promise<void>
|
||||
async syncRelationship(model: BaseModel, relationshipName: string, relatedModels: BaseModel[]): Promise<void>
|
||||
|
||||
// Caching
|
||||
getCachedRelationship(model: BaseModel, relationshipName: string): any
|
||||
setCachedRelationship(model: BaseModel, relationshipName: string, data: any): void
|
||||
clearRelationshipCache(model: BaseModel, relationshipName?: string): void
|
||||
}
|
||||
```
|
||||
|
||||
## Migration System
|
||||
|
||||
### MigrationManager Class
|
||||
**Location**: `src/framework/migrations/MigrationManager.ts`
|
||||
|
||||
Handles schema evolution and data transformation:
|
||||
|
||||
```typescript
|
||||
export class MigrationManager {
|
||||
// Migration operations
|
||||
async runMigration(migrationId: string): Promise<MigrationResult>
|
||||
async rollbackMigration(migrationId: string): Promise<MigrationResult>
|
||||
async runPendingMigrations(): Promise<MigrationResult[]>
|
||||
|
||||
// Migration management
|
||||
registerMigration(migration: Migration): void
|
||||
getPendingMigrations(): Migration[]
|
||||
getAppliedMigrations(): Promise<string[]>
|
||||
|
||||
// Status
|
||||
getMigrationStatus(): Promise<MigrationStatus>
|
||||
}
|
||||
|
||||
interface Migration {
|
||||
id: string;
|
||||
version: string;
|
||||
name: string;
|
||||
description: string;
|
||||
targetModels: string[];
|
||||
up: MigrationOperation[];
|
||||
down: MigrationOperation[];
|
||||
dependencies?: string[];
|
||||
validators?: MigrationValidator[];
|
||||
}
|
||||
```
|
||||
|
||||
### MigrationBuilder Class
|
||||
**Location**: `src/framework/migrations/MigrationBuilder.ts`
|
||||
|
||||
Fluent interface for creating migrations:
|
||||
|
||||
```typescript
|
||||
export function createMigration(name: string, version: string): MigrationBuilder {
|
||||
return new MigrationBuilder(name, version);
|
||||
}
|
||||
|
||||
export class MigrationBuilder {
|
||||
// Field operations
|
||||
addField(modelName: string, fieldName: string, config: FieldConfig): MigrationBuilder
|
||||
removeField(modelName: string, fieldName: string): MigrationBuilder
|
||||
modifyField(modelName: string, fieldName: string, config: FieldConfig): MigrationBuilder
|
||||
renameField(modelName: string, oldName: string, newName: string): MigrationBuilder
|
||||
|
||||
// Index operations
|
||||
addIndex(modelName: string, fields: string[], options?: IndexOptions): MigrationBuilder
|
||||
removeIndex(modelName: string, indexName: string): MigrationBuilder
|
||||
|
||||
// Data transformation
|
||||
transformData(modelName: string, transformer: (data: any) => any): MigrationBuilder
|
||||
|
||||
// Validation
|
||||
addValidator(name: string, validator: MigrationValidator): MigrationBuilder
|
||||
|
||||
// Build migration
|
||||
build(): Migration
|
||||
}
|
||||
```
|
||||
|
||||
## Caching System
|
||||
|
||||
### QueryCache Class
|
||||
**Location**: `src/framework/query/QueryCache.ts`
|
||||
|
||||
Intelligent caching of query results:
|
||||
|
||||
```typescript
|
||||
export class QueryCache {
|
||||
// Cache operations
|
||||
get(key: string): Promise<any>
|
||||
set(key: string, value: any, ttl?: number): Promise<void>
|
||||
delete(key: string): Promise<void>
|
||||
clear(): Promise<void>
|
||||
|
||||
// Cache management
|
||||
invalidateModelCache(modelName: string): Promise<void>
|
||||
invalidateUserCache(userId: string): Promise<void>
|
||||
|
||||
// Statistics
|
||||
getStats(): CacheStats
|
||||
getHitRate(): number
|
||||
}
|
||||
```
|
||||
|
||||
### RelationshipCache Class
|
||||
**Location**: `src/framework/relationships/RelationshipCache.ts`
|
||||
|
||||
Specialized caching for relationship data:
|
||||
|
||||
```typescript
|
||||
export class RelationshipCache {
|
||||
// Relationship caching
|
||||
getCachedRelationship(modelId: string, relationshipName: string): any
|
||||
setCachedRelationship(modelId: string, relationshipName: string, data: any, ttl?: number): void
|
||||
invalidateRelationship(modelId: string, relationshipName: string): void
|
||||
|
||||
// Batch operations
|
||||
preloadRelationships(modelIds: string[], relationshipNames: string[]): Promise<void>
|
||||
warmCache(modelName: string, relationshipName: string): Promise<void>
|
||||
}
|
||||
```
|
||||
|
||||
## Type Definitions
|
||||
|
||||
### Framework Types
|
||||
**Location**: `src/framework/types/framework.ts`
|
||||
|
||||
```typescript
|
||||
export interface FrameworkConfig {
|
||||
cache?: CacheConfig;
|
||||
queryOptimization?: QueryOptimizationConfig;
|
||||
automaticPinning?: PinningConfig;
|
||||
pubsub?: PubSubConfig;
|
||||
development?: DevelopmentConfig;
|
||||
}
|
||||
|
||||
export interface CacheConfig {
|
||||
enabled?: boolean;
|
||||
maxSize?: number;
|
||||
ttl?: number;
|
||||
}
|
||||
|
||||
export type StoreType = 'docstore' | 'eventlog' | 'keyvalue' | 'counter' | 'feed';
|
||||
```
|
||||
|
||||
### Model Types
|
||||
**Location**: `src/framework/types/models.ts`
|
||||
|
||||
```typescript
|
||||
export interface FieldConfig {
|
||||
type: FieldType;
|
||||
required?: boolean;
|
||||
unique?: boolean;
|
||||
default?: any | (() => any);
|
||||
validate?: (value: any) => boolean;
|
||||
transform?: (value: any) => any;
|
||||
serialize?: boolean;
|
||||
index?: boolean;
|
||||
virtual?: boolean;
|
||||
}
|
||||
|
||||
export type FieldType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date';
|
||||
|
||||
export interface RelationshipConfig {
|
||||
type: 'belongsTo' | 'hasMany' | 'hasOne' | 'manyToMany';
|
||||
target: () => typeof BaseModel;
|
||||
foreignKey: string;
|
||||
localKey?: string;
|
||||
through?: string;
|
||||
throughForeignKey?: string;
|
||||
throughLocalKey?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Query Types
|
||||
**Location**: `src/framework/types/queries.ts`
|
||||
|
||||
```typescript
|
||||
export interface QueryOptions {
|
||||
where?: WhereClause[];
|
||||
orderBy?: OrderByClause[];
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
with?: string[];
|
||||
cache?: boolean | number;
|
||||
}
|
||||
|
||||
export interface WhereClause {
|
||||
field: string;
|
||||
operator: QueryOperator;
|
||||
value: any;
|
||||
boolean: 'and' | 'or';
|
||||
}
|
||||
|
||||
export interface OrderByClause {
|
||||
field: string;
|
||||
direction: 'asc' | 'desc';
|
||||
}
|
||||
|
||||
export interface PaginationResult<T> {
|
||||
data: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
perPage: number;
|
||||
totalPages: number;
|
||||
hasNext: boolean;
|
||||
hasPrev: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Framework Errors
|
||||
```typescript
|
||||
export class DebrosFrameworkError extends Error {
|
||||
code: string;
|
||||
details?: any;
|
||||
|
||||
constructor(message: string, code?: string, details?: any) {
|
||||
super(message);
|
||||
this.name = 'DebrosFrameworkError';
|
||||
this.code = code || 'UNKNOWN_ERROR';
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidationError extends DebrosFrameworkError {
|
||||
field: string;
|
||||
value: any;
|
||||
constraint: string;
|
||||
}
|
||||
|
||||
export class QueryError extends DebrosFrameworkError {
|
||||
query: string;
|
||||
parameters?: any[];
|
||||
}
|
||||
|
||||
export class RelationshipError extends DebrosFrameworkError {
|
||||
modelName: string;
|
||||
relationshipName: string;
|
||||
relatedModel: string;
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Query Optimization
|
||||
**Location**: `src/framework/query/QueryOptimizer.ts`
|
||||
|
||||
```typescript
|
||||
export class QueryOptimizer {
|
||||
// Query optimization
|
||||
optimizeQuery(query: QueryBuilder<any>): QueryBuilder<any>
|
||||
analyzeQueryPerformance(query: QueryBuilder<any>): Promise<QueryAnalysis>
|
||||
suggestIndexes(modelName: string): Promise<IndexSuggestion[]>
|
||||
|
||||
// Statistics
|
||||
getSlowQueries(): Promise<SlowQuery[]>
|
||||
getQueryStats(): Promise<QueryStats>
|
||||
}
|
||||
```
|
||||
|
||||
### LazyLoader Class
|
||||
**Location**: `src/framework/relationships/LazyLoader.ts`
|
||||
|
||||
```typescript
|
||||
export class LazyLoader {
|
||||
// Lazy loading
|
||||
async loadOnDemand(model: BaseModel, relationshipName: string): Promise<any>
|
||||
async batchLoad(models: BaseModel[], relationshipName: string): Promise<void>
|
||||
|
||||
// Configuration
|
||||
setBatchSize(size: number): void
|
||||
setLoadingStrategy(strategy: 'immediate' | 'batched' | 'deferred'): void
|
||||
}
|
||||
```
|
||||
|
||||
This technical reference provides the implementation details needed to work effectively with the DebrosFramework codebase.
|
Reference in New Issue
Block a user