feat: Add contributing guidelines and development setup documentation
- Created a comprehensive Code Guidelines document outlining coding standards and best practices for DebrosFramework. - Added a Development Setup guide to assist contributors in setting up their environment. - Introduced an Overview document to welcome new contributors and explain the project's status and contribution areas. - Updated the intro.md to reflect the current development status of DebrosFramework. - Modified sidebars.ts to include new contributing documentation in the navigation. - Enhanced package.json description for clarity and added relevant keywords. - Updated version information in DebrosFramework.ts and index.ts to reflect the current beta version.
This commit is contained in:
parent
f4be989616
commit
869049c679
347
CONTRIBUTING.md
Normal file
347
CONTRIBUTING.md
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
# Contributing to DebrosFramework
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to DebrosFramework! This document provides guidelines and information for contributors.
|
||||||
|
|
||||||
|
## Development Status
|
||||||
|
|
||||||
|
DebrosFramework is currently in **beta (v0.5.0-beta)** and under active development. We welcome contributions from the community to help improve the framework.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js 18.0 or higher
|
||||||
|
- npm or pnpm package manager
|
||||||
|
- Git
|
||||||
|
- TypeScript knowledge
|
||||||
|
- Familiarity with IPFS and OrbitDB concepts
|
||||||
|
|
||||||
|
### Development Setup
|
||||||
|
|
||||||
|
1. **Fork and Clone**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/YOUR_USERNAME/network.git
|
||||||
|
cd network
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install Dependencies**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Build the Project**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Run Tests**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Unit tests
|
||||||
|
pnpm run test:unit
|
||||||
|
|
||||||
|
# Integration tests
|
||||||
|
pnpm run test:real
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/framework/
|
||||||
|
├── core/ # Core framework components
|
||||||
|
├── models/ # Model system and decorators
|
||||||
|
├── query/ # Query builder and execution
|
||||||
|
├── relationships/ # Relationship management
|
||||||
|
├── sharding/ # Data sharding logic
|
||||||
|
├── migrations/ # Schema migration system
|
||||||
|
├── pinning/ # Automatic pinning features
|
||||||
|
├── pubsub/ # Event publishing system
|
||||||
|
└── types/ # TypeScript type definitions
|
||||||
|
|
||||||
|
docs/docs/ # Documentation source
|
||||||
|
tests/ # Test suites
|
||||||
|
└── real-integration/ # Integration test scenarios
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to Contribute
|
||||||
|
|
||||||
|
### Types of Contributions
|
||||||
|
|
||||||
|
We welcome the following types of contributions:
|
||||||
|
|
||||||
|
1. **🐛 Bug Reports** - Report issues and bugs
|
||||||
|
2. **✨ Feature Requests** - Suggest new features
|
||||||
|
3. **📖 Documentation** - Improve docs and examples
|
||||||
|
4. **🔧 Code Contributions** - Bug fixes and new features
|
||||||
|
5. **🧪 Testing** - Add tests and improve test coverage
|
||||||
|
6. **💡 Examples** - Create usage examples and tutorials
|
||||||
|
|
||||||
|
### Bug Reports
|
||||||
|
|
||||||
|
When reporting bugs, please include:
|
||||||
|
|
||||||
|
- **Clear description** of the issue
|
||||||
|
- **Steps to reproduce** the problem
|
||||||
|
- **Expected vs actual behavior**
|
||||||
|
- **Environment details** (Node.js version, OS, etc.)
|
||||||
|
- **Code examples** that demonstrate the issue
|
||||||
|
- **Error messages** and stack traces
|
||||||
|
|
||||||
|
Use our bug report template:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
## Bug Description
|
||||||
|
|
||||||
|
[Clear description of the bug]
|
||||||
|
|
||||||
|
## Steps to Reproduce
|
||||||
|
|
||||||
|
1. [First step]
|
||||||
|
2. [Second step]
|
||||||
|
3. [etc.]
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
[What you expected to happen]
|
||||||
|
|
||||||
|
## Actual Behavior
|
||||||
|
|
||||||
|
[What actually happened]
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
|
||||||
|
- DebrosFramework version: [version]
|
||||||
|
- Node.js version: [version]
|
||||||
|
- OS: [operating system]
|
||||||
|
|
||||||
|
## Code Example
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Minimal code example that reproduces the issue
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
````
|
||||||
|
|
||||||
|
### Feature Requests
|
||||||
|
|
||||||
|
For feature requests, please provide:
|
||||||
|
|
||||||
|
- **Clear use case** and motivation
|
||||||
|
- **Detailed description** of the proposed feature
|
||||||
|
- **API design suggestions** (if applicable)
|
||||||
|
- **Examples** of how it would be used
|
||||||
|
- **Alternatives considered**
|
||||||
|
|
||||||
|
### Code Contributions
|
||||||
|
|
||||||
|
#### Before You Start
|
||||||
|
|
||||||
|
1. **Check existing issues** to avoid duplicate work
|
||||||
|
2. **Discuss large changes** in an issue first
|
||||||
|
3. **Follow the coding standards** outlined below
|
||||||
|
4. **Write tests** for your changes
|
||||||
|
5. **Update documentation** as needed
|
||||||
|
|
||||||
|
#### Development Workflow
|
||||||
|
|
||||||
|
1. **Create a feature branch**
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
````
|
||||||
|
|
||||||
|
2. **Make your changes**
|
||||||
|
|
||||||
|
- Write clean, well-documented code
|
||||||
|
- Follow TypeScript best practices
|
||||||
|
- Add tests for new functionality
|
||||||
|
- Update relevant documentation
|
||||||
|
|
||||||
|
3. **Test your changes**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run test:unit
|
||||||
|
pnpm run test:real
|
||||||
|
pnpm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Commit your changes**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: add new feature description"
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Push and create PR**
|
||||||
|
```bash
|
||||||
|
git push origin feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Commit Message Format
|
||||||
|
|
||||||
|
We use conventional commits for consistent commit messages:
|
||||||
|
|
||||||
|
```
|
||||||
|
type(scope): description
|
||||||
|
|
||||||
|
body (optional)
|
||||||
|
|
||||||
|
footer (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Types:**
|
||||||
|
|
||||||
|
- `feat`: New features
|
||||||
|
- `fix`: Bug fixes
|
||||||
|
- `docs`: Documentation changes
|
||||||
|
- `style`: Code style changes (formatting, etc.)
|
||||||
|
- `refactor`: Code refactoring
|
||||||
|
- `test`: Adding or updating tests
|
||||||
|
- `chore`: Maintenance tasks
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(models): add support for computed fields
|
||||||
|
fix(query): resolve relationship loading issue
|
||||||
|
docs(readme): update installation instructions
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Code Style Guidelines
|
||||||
|
|
||||||
|
1. **TypeScript**
|
||||||
|
|
||||||
|
- Use strict TypeScript configuration
|
||||||
|
- Provide proper type annotations
|
||||||
|
- Use interfaces for object types
|
||||||
|
- Follow naming conventions
|
||||||
|
|
||||||
|
2. **Formatting**
|
||||||
|
|
||||||
|
- Use Prettier for code formatting
|
||||||
|
- Run `pnpm run format` before committing
|
||||||
|
- Use 2 spaces for indentation
|
||||||
|
|
||||||
|
3. **ESLint**
|
||||||
|
|
||||||
|
- Follow ESLint rules
|
||||||
|
- Run `pnpm run lint` and fix any issues
|
||||||
|
- Use `pnpm run lint:fix` for auto-fixes
|
||||||
|
|
||||||
|
4. **Documentation**
|
||||||
|
- Add JSDoc comments for public APIs
|
||||||
|
- Update relevant documentation files
|
||||||
|
- Include code examples where appropriate
|
||||||
|
|
||||||
|
#### Testing Guidelines
|
||||||
|
|
||||||
|
1. **Unit Tests**
|
||||||
|
|
||||||
|
- Write tests for all new functionality
|
||||||
|
- Use Jest for unit testing
|
||||||
|
- Aim for high code coverage
|
||||||
|
- Test edge cases and error conditions
|
||||||
|
|
||||||
|
2. **Integration Tests**
|
||||||
|
|
||||||
|
- Add integration tests for significant features
|
||||||
|
- Test real-world scenarios
|
||||||
|
- Use the blog scenario tests as reference
|
||||||
|
|
||||||
|
3. **Test Structure**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
describe('FeatureName', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Setup
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should behave correctly in normal case', () => {
|
||||||
|
// Test implementation
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle edge case', () => {
|
||||||
|
// Edge case test
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error for invalid input', () => {
|
||||||
|
// Error case test
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### Documentation Structure
|
||||||
|
|
||||||
|
- **README.md** - Overview and quick start
|
||||||
|
- **docs/docs/intro.md** - Framework introduction
|
||||||
|
- **docs/docs/getting-started.md** - Setup guide
|
||||||
|
- **docs/docs/core-concepts/** - Architecture and concepts
|
||||||
|
- **docs/docs/api/** - API reference
|
||||||
|
- **docs/docs/examples/** - Usage examples
|
||||||
|
|
||||||
|
### Writing Documentation
|
||||||
|
|
||||||
|
1. **Use clear, concise language**
|
||||||
|
2. **Provide code examples**
|
||||||
|
3. **Include both basic and advanced usage**
|
||||||
|
4. **Keep examples up-to-date**
|
||||||
|
5. **Add diagrams where helpful**
|
||||||
|
|
||||||
|
### Building Documentation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd docs
|
||||||
|
npm install
|
||||||
|
npm run start # Development server
|
||||||
|
npm run build # Production build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
Releases are managed by the core team and follow semantic versioning:
|
||||||
|
|
||||||
|
- **Patch** (0.5.1): Bug fixes and small improvements
|
||||||
|
- **Minor** (0.6.0): New features, backward compatible
|
||||||
|
- **Major** (1.0.0): Breaking changes
|
||||||
|
|
||||||
|
## Community Guidelines
|
||||||
|
|
||||||
|
### Code of Conduct
|
||||||
|
|
||||||
|
We are committed to providing a welcoming and inclusive environment. Please:
|
||||||
|
|
||||||
|
- **Be respectful** and considerate
|
||||||
|
- **Use inclusive language**
|
||||||
|
- **Accept constructive feedback**
|
||||||
|
- **Focus on what's best** for the community
|
||||||
|
- **Show empathy** towards other contributors
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
|
||||||
|
- **GitHub Issues** - For bug reports and feature requests
|
||||||
|
- **GitHub Discussions** - For questions and community discussion
|
||||||
|
- **Discord** - For real-time chat and support
|
||||||
|
|
||||||
|
## Recognition
|
||||||
|
|
||||||
|
Contributors will be recognized in:
|
||||||
|
|
||||||
|
- **CONTRIBUTORS.md** file
|
||||||
|
- **Release notes** for significant contributions
|
||||||
|
- **Documentation credits** for doc contributions
|
||||||
|
|
||||||
|
## Questions?
|
||||||
|
|
||||||
|
If you have questions about contributing, please:
|
||||||
|
|
||||||
|
1. Check existing documentation
|
||||||
|
2. Search GitHub issues
|
||||||
|
3. Ask in GitHub Discussions
|
||||||
|
4. Contact the maintainers
|
||||||
|
|
||||||
|
Thank you for contributing to DebrosFramework! 🚀
|
537
README.md
537
README.md
@ -1,21 +1,18 @@
|
|||||||
# @debros/network
|
# @debros/network
|
||||||
|
|
||||||
Core networking functionality for the Debros decentralized network. This package provides a powerful database interface with advanced features built on IPFS and OrbitDB for decentralized applications.
|
**DebrosFramework** - A powerful Node.js framework that provides an ORM-like abstraction over OrbitDB and IPFS, making it easy to build scalable decentralized applications.
|
||||||
|
|
||||||
## Features
|
## What is DebrosFramework?
|
||||||
|
|
||||||
- Rich database-like API with TypeScript support
|
DebrosFramework simplifies the development of decentralized applications by providing:
|
||||||
- Multiple database store types (KeyValue, Document, Feed, Counter)
|
|
||||||
- Document operations with schema validation
|
- **Model-based Abstraction**: Define your data models using decorators and TypeScript classes
|
||||||
- Advanced querying with pagination, sorting and filtering
|
- **Automatic Database Management**: Handle user-scoped and global databases automatically
|
||||||
- Transaction support for batch operations
|
- **Smart Sharding**: Distribute data across multiple databases for scalability
|
||||||
- Built-in file storage with metadata
|
- **Advanced Query System**: Rich query capabilities with relationship loading and caching
|
||||||
- Real-time subscriptions for data changes
|
- **Automatic Features**: Built-in pinning strategies and PubSub event publishing
|
||||||
- Memory caching for performance
|
- **Migration System**: Schema evolution and data transformation capabilities
|
||||||
- Connection pooling for managing multiple database instances
|
- **Type Safety**: Full TypeScript support with strong typing throughout
|
||||||
- Index creation for faster queries
|
|
||||||
- Comprehensive error handling with error codes
|
|
||||||
- Performance metrics and monitoring
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -23,280 +20,366 @@ Core networking functionality for the Debros decentralized network. This package
|
|||||||
npm install @debros/network
|
npm install @debros/network
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic Usage
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Define Your Models
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { initDB, create, get, query, uploadFile, logger } from '@debros/network';
|
import { BaseModel, Model, Field, HasMany } from '@debros/network';
|
||||||
|
|
||||||
// Initialize the database service
|
@Model({
|
||||||
async function startApp() {
|
scope: 'global',
|
||||||
try {
|
type: 'docstore',
|
||||||
// Initialize with default configuration
|
sharding: { strategy: 'hash', count: 4, key: 'id' },
|
||||||
await initDB();
|
})
|
||||||
logger.info('Database initialized successfully');
|
export class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
// Create a new user document
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
const userId = 'user123';
|
email: string;
|
||||||
const user = {
|
|
||||||
username: 'johndoe',
|
|
||||||
walletAddress: '0x1234567890',
|
|
||||||
avatar: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await create('users', userId, user);
|
@HasMany(() => Post, 'userId')
|
||||||
logger.info(`Created user with ID: ${result.id}`);
|
posts: Post[];
|
||||||
|
|
||||||
// Get a user by ID
|
|
||||||
const retrievedUser = await get('users', userId);
|
|
||||||
logger.info('User:', retrievedUser);
|
|
||||||
|
|
||||||
// Query users with filtering
|
|
||||||
const activeUsers = await query('users', (user) => user.isActive === true, {
|
|
||||||
limit: 10,
|
|
||||||
sort: { field: 'createdAt', order: 'desc' },
|
|
||||||
});
|
|
||||||
logger.info(`Found ${activeUsers.total} active users`);
|
|
||||||
|
|
||||||
// Upload a file
|
|
||||||
const fileData = Buffer.from('File content');
|
|
||||||
const fileUpload = await uploadFile(fileData, { filename: 'document.txt' });
|
|
||||||
logger.info(`Uploaded file with CID: ${fileUpload.cid}`);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('Failed to start app:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startApp();
|
@Model({
|
||||||
|
scope: 'user',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: { strategy: 'user', count: 2, key: 'userId' },
|
||||||
|
})
|
||||||
|
export class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Database Store Types
|
### 2. Initialize the Framework
|
||||||
|
|
||||||
The library supports multiple OrbitDB store types, each optimized for different use cases:
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { create, get, update, StoreType } from '@debros/network';
|
import { DebrosFramework } from '@debros/network';
|
||||||
|
import { setupOrbitDB, setupIPFS } from './services';
|
||||||
|
|
||||||
// Default KeyValue store (for general use)
|
async function startApp() {
|
||||||
await create('users', 'user1', { name: 'Alice' });
|
// Initialize services
|
||||||
|
const orbitDBService = await setupOrbitDB();
|
||||||
|
const ipfsService = await setupIPFS();
|
||||||
|
|
||||||
// Document store (better for complex documents with indexing)
|
// Initialize framework
|
||||||
await create(
|
const framework = new DebrosFramework({
|
||||||
'posts',
|
features: {
|
||||||
'post1',
|
queryCache: true,
|
||||||
{ title: 'Hello', content: '...' },
|
automaticPinning: true,
|
||||||
{ storeType: StoreType.DOCSTORE },
|
pubsub: true,
|
||||||
);
|
|
||||||
|
|
||||||
// Feed/EventLog store (append-only, good for immutable logs)
|
|
||||||
await create('events', 'evt1', { type: 'login', user: 'alice' }, { storeType: StoreType.FEED });
|
|
||||||
|
|
||||||
// Counter store (for numeric counters)
|
|
||||||
await create('stats', 'visits', { value: 0 }, { storeType: StoreType.COUNTER });
|
|
||||||
|
|
||||||
// Increment a counter
|
|
||||||
await update('stats', 'visits', { increment: 1 }, { storeType: StoreType.COUNTER });
|
|
||||||
|
|
||||||
// Get counter value
|
|
||||||
const stats = await get('stats', 'visits', { storeType: StoreType.COUNTER });
|
|
||||||
console.log(`Visit count: ${stats.value}`);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Advanced Features
|
|
||||||
|
|
||||||
### Schema Validation
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { defineSchema, create } from '@debros/network';
|
|
||||||
|
|
||||||
// Define a schema
|
|
||||||
defineSchema('users', {
|
|
||||||
properties: {
|
|
||||||
username: {
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
min: 3,
|
|
||||||
max: 20,
|
|
||||||
},
|
},
|
||||||
email: {
|
});
|
||||||
type: 'string',
|
|
||||||
pattern: '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$',
|
|
||||||
},
|
|
||||||
age: {
|
|
||||||
type: 'number',
|
|
||||||
min: 18,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: ['username'],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Document creation will be validated against the schema
|
await framework.initialize(orbitDBService, ipfsService);
|
||||||
await create('users', 'user1', {
|
console.log('✅ DebrosFramework initialized successfully!');
|
||||||
|
|
||||||
|
// Create a user
|
||||||
|
const user = await User.create({
|
||||||
username: 'alice',
|
username: 'alice',
|
||||||
email: 'alice@example.com',
|
email: 'alice@example.com',
|
||||||
age: 25,
|
});
|
||||||
});
|
|
||||||
|
// Create a post
|
||||||
|
const post = await Post.create({
|
||||||
|
title: 'My First Post',
|
||||||
|
content: 'Hello DebrosFramework!',
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Query with relationships
|
||||||
|
const usersWithPosts = await User.query().with(['posts']).where('username', 'alice').find();
|
||||||
|
|
||||||
|
console.log('User:', usersWithPosts[0]);
|
||||||
|
console.log('Posts:', usersWithPosts[0].posts);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Transactions
|
## Key Features
|
||||||
|
|
||||||
|
### 🏗️ Model-Driven Development
|
||||||
|
|
||||||
|
Define your data models using familiar decorator patterns:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { createTransaction, commitTransaction } from '@debros/network';
|
@Model({
|
||||||
|
scope: 'user',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: { strategy: 'hash', count: 4, key: 'userId' },
|
||||||
|
})
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
// Create a transaction
|
@BelongsTo(() => User, 'userId')
|
||||||
const transaction = createTransaction();
|
user: User;
|
||||||
|
}
|
||||||
// Add multiple operations
|
|
||||||
transaction
|
|
||||||
.create('posts', 'post1', { title: 'Hello World', content: '...' })
|
|
||||||
.update('users', 'user1', { postCount: 1 })
|
|
||||||
.delete('drafts', 'draft1');
|
|
||||||
|
|
||||||
// Commit all operations
|
|
||||||
const result = await commitTransaction(transaction);
|
|
||||||
console.log(`Transaction completed with ${result.results.length} operations`);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Event Subscriptions
|
### 🔍 Powerful Query System
|
||||||
|
|
||||||
|
Build complex queries with relationship loading:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { subscribe } from '@debros/network';
|
const users = await User.query()
|
||||||
|
.where('isActive', true)
|
||||||
// Subscribe to document changes
|
.where('registeredAt', '>', Date.now() - 30 * 24 * 60 * 60 * 1000)
|
||||||
const unsubscribe = subscribe('document:created', (data) => {
|
.with(['posts', 'followers'])
|
||||||
console.log(`New document created in ${data.collection}:`, data.id);
|
.orderBy('username')
|
||||||
console.log('Document data:', data.document);
|
.limit(20)
|
||||||
});
|
.find();
|
||||||
|
|
||||||
// Other event types
|
|
||||||
// subscribe('document:updated', (data) => { ... });
|
|
||||||
// subscribe('document:deleted', (data) => { ... });
|
|
||||||
|
|
||||||
// Later, unsubscribe when done
|
|
||||||
unsubscribe();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Pagination and Sorting
|
### 🚀 Automatic Scaling
|
||||||
|
|
||||||
|
Handle millions of users with automatic sharding and pinning:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { list, query } from '@debros/network';
|
// Framework automatically:
|
||||||
|
// - Creates user-scoped databases
|
||||||
// List with pagination and sorting
|
// - Distributes data across shards
|
||||||
const page1 = await list('users', {
|
// - Manages pinning strategies
|
||||||
limit: 10,
|
// - Optimizes query routing
|
||||||
offset: 0,
|
|
||||||
sort: { field: 'createdAt', order: 'desc' },
|
|
||||||
});
|
|
||||||
|
|
||||||
// Query with pagination
|
|
||||||
const results = await query('users', (user) => user.age > 21, { limit: 10, offset: 20 });
|
|
||||||
|
|
||||||
console.log(`Found ${results.total} matches, showing ${results.documents.length}`);
|
|
||||||
console.log(`Has more pages: ${results.hasMore}`);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### TypeScript Support
|
### 🔄 Schema Evolution
|
||||||
|
|
||||||
|
Migrate your data structures safely:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { get, update, query } from '@debros/network';
|
const migration = createMigration('add_user_profiles', '1.1.0')
|
||||||
|
.addField('User', 'profilePicture', { type: 'string', required: false })
|
||||||
|
.addField('User', 'bio', { type: 'string', required: false })
|
||||||
|
.transformData('User', (user) => ({
|
||||||
|
...user,
|
||||||
|
displayName: user.username || 'Anonymous',
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
interface User {
|
### 🔗 Rich Relationships
|
||||||
username: string;
|
|
||||||
email: string;
|
Handle complex relationships between models:
|
||||||
age: number;
|
|
||||||
createdAt: number;
|
```typescript
|
||||||
updatedAt: number;
|
@Model({ scope: 'global' })
|
||||||
|
class User extends BaseModel {
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
|
||||||
|
@ManyToMany(() => User, 'followers', 'following')
|
||||||
|
followers: User[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type-safe operations
|
// Load user with all relationships
|
||||||
const user = await get<User>('users', 'user1');
|
const user = await User.findById(userId, {
|
||||||
|
with: ['posts.comments', 'followers.posts'],
|
||||||
await update<User>('users', 'user1', { age: 26 });
|
});
|
||||||
|
|
||||||
const results = await query<User>('users', (user) => user.age > 21);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Connection Management
|
### ⚡ Performance Features
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { initDB, closeConnection } from '@debros/network';
|
// Query caching
|
||||||
|
const cachedUsers = await User.query()
|
||||||
|
.where('isActive', true)
|
||||||
|
.cache(300) // Cache for 5 minutes
|
||||||
|
.find();
|
||||||
|
|
||||||
// Create multiple connections
|
// Eager loading
|
||||||
const conn1 = await initDB('connection1');
|
const usersWithPosts = await User.query().with(['posts.comments']).find();
|
||||||
const conn2 = await initDB('connection2');
|
|
||||||
|
|
||||||
// Use specific connection
|
// Optimized pagination
|
||||||
await create('users', 'user1', { name: 'Alice' }, { connectionId: conn1 });
|
const page = await User.query().orderBy('createdAt', 'desc').paginate(1, 20);
|
||||||
|
```
|
||||||
|
|
||||||
// Close a specific connection
|
### 🎯 Model Hooks
|
||||||
await closeConnection(conn1);
|
|
||||||
|
```typescript
|
||||||
|
export class User extends BaseModel {
|
||||||
|
@BeforeCreate()
|
||||||
|
async beforeCreate() {
|
||||||
|
this.createdAt = Date.now();
|
||||||
|
// Hash password, validate data, etc.
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterCreate()
|
||||||
|
async afterCreate() {
|
||||||
|
// Send welcome email, create defaults, etc.
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Reference
|
## API Reference
|
||||||
|
|
||||||
### Core Database Operations
|
### Framework Management
|
||||||
|
|
||||||
- `initDB(connectionId?: string): Promise<string>` - Initialize the database
|
- `new DebrosFramework(config?)` - Create framework instance
|
||||||
- `create<T>(collection, id, data, options?): Promise<CreateResult>` - Create a document
|
- `framework.initialize(orbitDBService, ipfsService, config?)` - Initialize framework
|
||||||
- `get<T>(collection, id, options?): Promise<T | null>` - Get a document by ID
|
- `framework.start()` - Start the framework
|
||||||
- `update<T>(collection, id, data, options?): Promise<UpdateResult>` - Update a document
|
- `framework.stop()` - Stop the framework
|
||||||
- `remove(collection, id, options?): Promise<boolean>` - Delete a document
|
- `framework.getStatus()` - Get framework status
|
||||||
- `list<T>(collection, options?): Promise<PaginatedResult<T>>` - List documents with pagination
|
|
||||||
- `query<T>(collection, filter, options?): Promise<PaginatedResult<T>>` - Query documents
|
|
||||||
- `stopDB(): Promise<void>` - Stop the database service
|
|
||||||
|
|
||||||
### Store Types
|
### Model Operations
|
||||||
|
|
||||||
- `StoreType.KEYVALUE` - Key-value pair storage (default)
|
- `Model.create(data)` - Create a new model instance
|
||||||
- `StoreType.DOCSTORE` - Document storage with indexing
|
- `Model.findById(id, options?)` - Find model by ID
|
||||||
- `StoreType.FEED` - Append-only log
|
- `Model.findOne(criteria, options?)` - Find single model
|
||||||
- `StoreType.EVENTLOG` - Alias for FEED
|
- `Model.query()` - Start a query builder
|
||||||
- `StoreType.COUNTER` - Numeric counter
|
- `model.save()` - Save model changes
|
||||||
|
- `model.delete()` - Delete model instance
|
||||||
|
|
||||||
### Schema Validation
|
### Query System
|
||||||
|
|
||||||
- `defineSchema(collection, schema): void` - Define a schema for a collection
|
- `Model.query().where(field, operator, value)` - Add where condition
|
||||||
|
- `Model.query().with(relationships)` - Eager load relationships
|
||||||
|
- `Model.query().orderBy(field, direction)` - Add ordering
|
||||||
|
- `Model.query().limit(count)` - Limit results
|
||||||
|
- `Model.query().offset(count)` - Add offset
|
||||||
|
- `Model.query().paginate(page, perPage)` - Paginate results
|
||||||
|
- `Model.query().cache(ttl)` - Cache query results
|
||||||
|
- `Model.query().find()` - Execute query
|
||||||
|
- `Model.query().count()` - Count results
|
||||||
|
|
||||||
### Transactions
|
### Decorators
|
||||||
|
|
||||||
- `createTransaction(connectionId?): Transaction` - Create a new transaction
|
- `@Model(config)` - Define model configuration
|
||||||
- `commitTransaction(transaction): Promise<{success, results}>` - Execute the transaction
|
- `@Field(config)` - Define field properties
|
||||||
- `Transaction.create<T>(collection, id, data): Transaction` - Add a create operation
|
- `@BelongsTo(target, foreignKey)` - Many-to-one relationship
|
||||||
- `Transaction.update<T>(collection, id, data): Transaction` - Add an update operation
|
- `@HasMany(target, foreignKey)` - One-to-many relationship
|
||||||
- `Transaction.delete(collection, id): Transaction` - Add a delete operation
|
- `@HasOne(target, foreignKey)` - One-to-one relationship
|
||||||
|
- `@ManyToMany(target, through)` - Many-to-many relationship
|
||||||
|
- `@BeforeCreate()`, `@AfterCreate()` - Lifecycle hooks
|
||||||
|
- `@BeforeUpdate()`, `@AfterUpdate()` - Update hooks
|
||||||
|
- `@BeforeDelete()`, `@AfterDelete()` - Delete hooks
|
||||||
|
|
||||||
### Event Subscriptions
|
### Migration System
|
||||||
|
|
||||||
- `subscribe(event, callback): () => void` - Subscribe to database events, returns unsubscribe function
|
- `createMigration(name, version)` - Create new migration
|
||||||
- Event types: 'document:created', 'document:updated', 'document:deleted'
|
- `migration.addField(model, field, config)` - Add field to model
|
||||||
|
- `migration.removeField(model, field)` - Remove field from model
|
||||||
### File Operations
|
- `migration.transformData(model, transformer)` - Transform existing data
|
||||||
|
- `migrationManager.runPendingMigrations()` - Run pending migrations
|
||||||
- `uploadFile(fileData, options?): Promise<FileUploadResult>` - Upload a file
|
|
||||||
- `getFile(cid, options?): Promise<FileResult>` - Get a file by CID
|
|
||||||
- `deleteFile(cid, options?): Promise<boolean>` - Delete a file
|
|
||||||
|
|
||||||
### Connection Management
|
|
||||||
|
|
||||||
- `closeConnection(connectionId): Promise<boolean>` - Close a specific connection
|
|
||||||
|
|
||||||
### Indexes and Performance
|
|
||||||
|
|
||||||
- `createIndex(collection, field, options?): Promise<boolean>` - Create an index
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
### Framework Configuration
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { config, initDB } from '@debros/network';
|
import { DebrosFramework, PRODUCTION_CONFIG, DEVELOPMENT_CONFIG } from '@debros/network';
|
||||||
|
|
||||||
// Configure (optional)
|
// Development configuration
|
||||||
config.env.fingerprint = 'my-unique-app-id';
|
const framework = new DebrosFramework({
|
||||||
config.env.port = 9000;
|
...DEVELOPMENT_CONFIG,
|
||||||
config.ipfs.blockstorePath = './custom-path/blockstore';
|
features: {
|
||||||
config.orbitdb.directory = './custom-path/orbitdb';
|
queryCache: true,
|
||||||
|
automaticPinning: false,
|
||||||
|
pubsub: true,
|
||||||
|
relationshipCache: true,
|
||||||
|
autoMigration: true,
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
queryTimeout: 30000,
|
||||||
|
batchSize: 50,
|
||||||
|
},
|
||||||
|
monitoring: {
|
||||||
|
enableMetrics: true,
|
||||||
|
logLevel: 'debug',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize with configuration
|
// Production configuration
|
||||||
await initDB();
|
const prodFramework = new DebrosFramework({
|
||||||
|
...PRODUCTION_CONFIG,
|
||||||
|
performance: {
|
||||||
|
queryTimeout: 10000,
|
||||||
|
batchSize: 200,
|
||||||
|
maxConcurrentOperations: 500,
|
||||||
|
},
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Model Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global', // 'user' or 'global'
|
||||||
|
type: 'docstore', // OrbitDB store type
|
||||||
|
sharding: {
|
||||||
|
strategy: 'hash', // 'hash', 'range', or 'user'
|
||||||
|
count: 4, // Number of shards
|
||||||
|
key: 'id', // Sharding key
|
||||||
|
},
|
||||||
|
pinning: {
|
||||||
|
strategy: 'popularity', // Pinning strategy
|
||||||
|
factor: 2,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class MyModel extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
DebrosFramework is built around several core components:
|
||||||
|
|
||||||
|
1. **Models & Decorators**: Define your 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
|
||||||
|
|
||||||
|
### Key Benefits
|
||||||
|
|
||||||
|
- **Scalability**: Automatic sharding and distributed data management
|
||||||
|
- **Performance**: Built-in caching, query optimization, and lazy loading
|
||||||
|
- **Developer Experience**: Familiar ORM patterns with TypeScript support
|
||||||
|
- **Flexibility**: Support for various data patterns and relationships
|
||||||
|
- **Reliability**: Comprehensive error handling and recovery mechanisms
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Ready to build your first decentralized application? Check out our comprehensive documentation:
|
||||||
|
|
||||||
|
- **[📖 Complete Documentation](./docs)** - Comprehensive guides and examples
|
||||||
|
- **[🚀 Getting Started Guide](./docs/docs/getting-started.md)** - Set up your development environment
|
||||||
|
- **[🏗️ Architecture Overview](./docs/docs/core-concepts/architecture.md)** - Understand how the framework works
|
||||||
|
- **[📝 API Reference](./docs/docs/api/overview.md)** - Complete API documentation
|
||||||
|
- **[💡 Examples](./docs/docs/examples/basic-usage.md)** - Practical usage examples
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run unit tests
|
||||||
|
npm run test:unit
|
||||||
|
|
||||||
|
# Run integration tests
|
||||||
|
npm run test:real
|
||||||
|
|
||||||
|
# Run specific blog scenario integration test
|
||||||
|
npm run test:blog-integration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the GNU GPL v3.0 License - see the [LICENSE](./LICENSE) file for details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**DebrosFramework** - Making decentralized application development as simple as traditional web development, while providing the benefits of distributed systems.
|
||||||
|
734
docs/docs/contributing/code-guidelines.md
Normal file
734
docs/docs/contributing/code-guidelines.md
Normal file
@ -0,0 +1,734 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# Code Guidelines
|
||||||
|
|
||||||
|
This document outlines the coding standards, best practices, and architectural principles for contributing to DebrosFramework.
|
||||||
|
|
||||||
|
## 🎯 Core Principles
|
||||||
|
|
||||||
|
### 1. Developer Experience First
|
||||||
|
|
||||||
|
Every API decision should prioritize developer experience:
|
||||||
|
|
||||||
|
- **Intuitive naming** - Use clear, descriptive names
|
||||||
|
- **Consistent patterns** - Follow established conventions
|
||||||
|
- **Helpful errors** - Provide actionable error messages
|
||||||
|
- **Complete TypeScript** - Full type safety and IntelliSense
|
||||||
|
|
||||||
|
### 2. Performance by Default
|
||||||
|
|
||||||
|
Optimize for common use cases:
|
||||||
|
|
||||||
|
- **Lazy loading** - Load data only when needed
|
||||||
|
- **Automatic caching** - Cache frequently accessed data
|
||||||
|
- **Efficient queries** - Optimize database operations
|
||||||
|
- **Memory management** - Clean up resources properly
|
||||||
|
|
||||||
|
### 3. Scalability Built-in
|
||||||
|
|
||||||
|
Design for applications with millions of users:
|
||||||
|
|
||||||
|
- **Automatic sharding** - Distribute data effectively
|
||||||
|
- **Parallel processing** - Execute operations concurrently
|
||||||
|
- **Resource optimization** - Use resources efficiently
|
||||||
|
- **Graceful degradation** - Handle failures elegantly
|
||||||
|
|
||||||
|
## 📝 TypeScript Standards
|
||||||
|
|
||||||
|
### Type Safety Requirements
|
||||||
|
|
||||||
|
All code must be fully typed with strict TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Explicit types
|
||||||
|
interface UserCreateData {
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
bio?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createUser(data: UserCreateData): Promise<User> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Bad - Using any
|
||||||
|
async function createUser(data: any): Promise<any> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interface Design
|
||||||
|
|
||||||
|
Use interfaces for all public APIs:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Clear interface definition
|
||||||
|
interface QueryOptions {
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
orderBy?: OrderByClause[];
|
||||||
|
with?: string[];
|
||||||
|
cache?: boolean | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Good - Generic interfaces
|
||||||
|
interface PaginatedResult<T> {
|
||||||
|
data: T[];
|
||||||
|
total: number;
|
||||||
|
page: number;
|
||||||
|
perPage: number;
|
||||||
|
hasMore: boolean;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
Use typed error classes with helpful messages:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Specific error types
|
||||||
|
export class ValidationError extends DebrosFrameworkError {
|
||||||
|
constructor(
|
||||||
|
public field: string,
|
||||||
|
public value: any,
|
||||||
|
public constraint: string,
|
||||||
|
message?: string,
|
||||||
|
) {
|
||||||
|
super(message || `Validation failed for field '${field}': ${constraint}`, 'VALIDATION_ERROR');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Good - Error usage
|
||||||
|
throw new ValidationError('email', 'invalid-email', 'must be valid email format');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generic Programming
|
||||||
|
|
||||||
|
Use generics for reusable components:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Generic model operations
|
||||||
|
abstract class BaseModel {
|
||||||
|
static async create<T extends BaseModel>(
|
||||||
|
this: ModelConstructor<T>,
|
||||||
|
data: Partial<T>,
|
||||||
|
): Promise<T> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
static query<T extends BaseModel>(this: ModelConstructor<T>): QueryBuilder<T> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏗️ Architecture Patterns
|
||||||
|
|
||||||
|
### Decorator Pattern
|
||||||
|
|
||||||
|
Use decorators consistently for metadata:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Consistent decorator usage
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: { strategy: 'hash', count: 4, key: 'id' },
|
||||||
|
})
|
||||||
|
export class User extends BaseModel {
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
validate: (value: string) => value.length >= 3,
|
||||||
|
})
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Pattern
|
||||||
|
|
||||||
|
Use dependency injection for services:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Service injection
|
||||||
|
export class DatabaseManager {
|
||||||
|
constructor(
|
||||||
|
private orbitDBService: FrameworkOrbitDBService,
|
||||||
|
private shardManager: ShardManager,
|
||||||
|
private configManager: ConfigManager,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async getDatabaseForModel<T extends BaseModel>(
|
||||||
|
modelClass: ModelConstructor<T>,
|
||||||
|
userId?: string,
|
||||||
|
): Promise<Database> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Builder Pattern
|
||||||
|
|
||||||
|
Use builders for complex configuration:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Fluent builder API
|
||||||
|
const migration = createMigration('add_user_profiles', '1.1.0')
|
||||||
|
.addField('User', 'profilePicture', { type: 'string', required: false })
|
||||||
|
.addField('User', 'bio', { type: 'string', required: false })
|
||||||
|
.transformData('User', (user) => ({
|
||||||
|
...user,
|
||||||
|
displayName: user.username || 'Anonymous',
|
||||||
|
}))
|
||||||
|
.addValidator('check_profile_data', async (context) => {
|
||||||
|
// Validation logic
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Async/Await Patterns
|
||||||
|
|
||||||
|
### Promise Handling
|
||||||
|
|
||||||
|
Always use async/await instead of Promise chains:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - async/await
|
||||||
|
async function getUserWithPosts(userId: string): Promise<User> {
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundError('User', userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const posts = await Post.query().where('userId', userId).orderBy('createdAt', 'desc').find();
|
||||||
|
|
||||||
|
user.posts = posts;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Bad - Promise chains
|
||||||
|
function getUserWithPosts(userId: string): Promise<User> {
|
||||||
|
return User.findById(userId).then((user) => {
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundError('User', userId);
|
||||||
|
}
|
||||||
|
return Post.query()
|
||||||
|
.where('userId', userId)
|
||||||
|
.orderBy('createdAt', 'desc')
|
||||||
|
.find()
|
||||||
|
.then((posts) => {
|
||||||
|
user.posts = posts;
|
||||||
|
return user;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Propagation
|
||||||
|
|
||||||
|
Let errors bubble up with proper context:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Error context
|
||||||
|
async function createUserWithProfile(userData: UserCreateData): Promise<User> {
|
||||||
|
try {
|
||||||
|
const user = await User.create(userData);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await UserProfile.create({
|
||||||
|
userId: user.id,
|
||||||
|
displayName: userData.username,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Clean up user if profile creation fails
|
||||||
|
await user.delete();
|
||||||
|
throw new OperationError('Failed to create user profile', 'USER_PROFILE_CREATION_FAILED', {
|
||||||
|
userId: user.id,
|
||||||
|
originalError: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof ValidationError) {
|
||||||
|
throw error; // Re-throw validation errors as-is
|
||||||
|
}
|
||||||
|
throw new OperationError('Failed to create user', 'USER_CREATION_FAILED', {
|
||||||
|
userData,
|
||||||
|
originalError: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 Testing Standards
|
||||||
|
|
||||||
|
### Unit Test Structure
|
||||||
|
|
||||||
|
Use consistent test structure:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Clear test structure
|
||||||
|
describe('User Model', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await setupTestDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await cleanupTestDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('should create user with valid data', async () => {
|
||||||
|
// Arrange
|
||||||
|
const userData = {
|
||||||
|
username: 'testuser',
|
||||||
|
email: 'test@example.com',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const user = await User.create(userData);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(user).toBeDefined();
|
||||||
|
expect(user.username).toBe(userData.username);
|
||||||
|
expect(user.email).toBe(userData.email);
|
||||||
|
expect(user.id).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw ValidationError for invalid email', async () => {
|
||||||
|
// Arrange
|
||||||
|
const userData = {
|
||||||
|
username: 'testuser',
|
||||||
|
email: 'invalid-email',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await expect(User.create(userData)).rejects.toThrow(ValidationError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('relationships', () => {
|
||||||
|
it('should load posts relationship', async () => {
|
||||||
|
// Test relationship loading
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration Test Patterns
|
||||||
|
|
||||||
|
Test real-world scenarios:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Integration test
|
||||||
|
describe('Blog Scenario Integration', () => {
|
||||||
|
let framework: DebrosFramework;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
framework = await setupFrameworkForTesting();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await framework.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle complete blog workflow', async () => {
|
||||||
|
// Create user
|
||||||
|
const user = await User.create({
|
||||||
|
username: 'blogger',
|
||||||
|
email: 'blogger@example.com',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create post
|
||||||
|
const post = await Post.create({
|
||||||
|
title: 'Test Post',
|
||||||
|
content: 'Test content',
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add comment
|
||||||
|
const comment = await Comment.create({
|
||||||
|
content: 'Great post!',
|
||||||
|
postId: post.id,
|
||||||
|
authorId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify relationships
|
||||||
|
const postWithComments = await Post.query()
|
||||||
|
.where('id', post.id)
|
||||||
|
.with(['comments.author'])
|
||||||
|
.findOne();
|
||||||
|
|
||||||
|
expect(postWithComments).toBeDefined();
|
||||||
|
expect(postWithComments!.comments).toHaveLength(1);
|
||||||
|
expect(postWithComments!.comments[0].author.username).toBe('blogger');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Performance Guidelines
|
||||||
|
|
||||||
|
### Query Optimization
|
||||||
|
|
||||||
|
Write efficient queries:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Optimized query
|
||||||
|
const recentPosts = await Post.query()
|
||||||
|
.where('publishedAt', '>', Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||||||
|
.where('isPublished', true)
|
||||||
|
.with(['author']) // Eager load to avoid N+1
|
||||||
|
.orderBy('publishedAt', 'desc')
|
||||||
|
.limit(20)
|
||||||
|
.cache(300) // Cache for 5 minutes
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// ❌ Bad - Inefficient query
|
||||||
|
const allPosts = await Post.query().find(); // Loads everything
|
||||||
|
const recentPosts = allPosts
|
||||||
|
.filter((p) => p.publishedAt > Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||||||
|
.filter((p) => p.isPublished)
|
||||||
|
.slice(0, 20);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
Clean up resources properly:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Resource cleanup
|
||||||
|
export class QueryCache {
|
||||||
|
private cache = new Map<string, CacheEntry>();
|
||||||
|
private cleanupInterval: NodeJS.Timeout;
|
||||||
|
|
||||||
|
constructor(private ttl: number = 300000) {
|
||||||
|
this.cleanupInterval = setInterval(() => {
|
||||||
|
this.cleanup();
|
||||||
|
}, this.ttl / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop(): Promise<void> {
|
||||||
|
if (this.cleanupInterval) {
|
||||||
|
clearInterval(this.cleanupInterval);
|
||||||
|
}
|
||||||
|
this.cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private cleanup(): void {
|
||||||
|
const now = Date.now();
|
||||||
|
for (const [key, entry] of this.cache.entries()) {
|
||||||
|
if (entry.expiresAt < now) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Async Performance
|
||||||
|
|
||||||
|
Use Promise.all for parallel operations:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Parallel execution
|
||||||
|
async function getUserDashboardData(userId: string): Promise<DashboardData> {
|
||||||
|
const [user, recentPosts, stats, notifications] = await Promise.all([
|
||||||
|
User.findById(userId),
|
||||||
|
Post.query().where('userId', userId).limit(5).find(),
|
||||||
|
getUserStats(userId),
|
||||||
|
getRecentNotifications(userId),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
recentPosts,
|
||||||
|
stats,
|
||||||
|
notifications,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Bad - Sequential execution
|
||||||
|
async function getUserDashboardData(userId: string): Promise<DashboardData> {
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
const recentPosts = await Post.query().where('userId', userId).limit(5).find();
|
||||||
|
const stats = await getUserStats(userId);
|
||||||
|
const notifications = await getRecentNotifications(userId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
recentPosts,
|
||||||
|
stats,
|
||||||
|
notifications,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Code Organization
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
|
||||||
|
Organize code logically:
|
||||||
|
|
||||||
|
```
|
||||||
|
src/framework/
|
||||||
|
├── core/ # Core framework components
|
||||||
|
│ ├── ConfigManager.ts
|
||||||
|
│ ├── DatabaseManager.ts
|
||||||
|
│ └── ModelRegistry.ts
|
||||||
|
├── models/ # Model system
|
||||||
|
│ ├── BaseModel.ts
|
||||||
|
│ └── decorators/
|
||||||
|
│ ├── Field.ts
|
||||||
|
│ ├── Model.ts
|
||||||
|
│ ├── relationships.ts
|
||||||
|
│ └── hooks.ts
|
||||||
|
├── query/ # Query system
|
||||||
|
│ ├── QueryBuilder.ts
|
||||||
|
│ ├── QueryExecutor.ts
|
||||||
|
│ └── QueryOptimizer.ts
|
||||||
|
└── types/ # Type definitions
|
||||||
|
├── framework.ts
|
||||||
|
├── models.ts
|
||||||
|
└── queries.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Import Organization
|
||||||
|
|
||||||
|
Use consistent import patterns:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Organized imports
|
||||||
|
// Node.js built-ins
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
// External packages
|
||||||
|
import { Database } from '@orbitdb/core';
|
||||||
|
import { CID } from 'multiformats';
|
||||||
|
|
||||||
|
// Framework internals
|
||||||
|
import { BaseModel } from '../models/BaseModel';
|
||||||
|
import { ConfigManager } from '../core/ConfigManager';
|
||||||
|
import { DatabaseManager } from '../core/DatabaseManager';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import type { ModelConfig, FieldConfig } from '../types/models';
|
||||||
|
import type { QueryOptions, QueryResult } from '../types/queries';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Export Patterns
|
||||||
|
|
||||||
|
Use consistent export patterns:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Clear exports
|
||||||
|
// Main class export
|
||||||
|
export class QueryBuilder<T extends BaseModel> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type exports
|
||||||
|
export type { QueryOptions, QueryResult, WhereClause, OrderByClause };
|
||||||
|
|
||||||
|
// Utility exports
|
||||||
|
export { buildWhereClause, optimizeQuery, validateQueryOptions };
|
||||||
|
|
||||||
|
// Default export for main functionality
|
||||||
|
export default QueryBuilder;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Documentation Standards
|
||||||
|
|
||||||
|
### JSDoc Comments
|
||||||
|
|
||||||
|
Document all public APIs:
|
||||||
|
|
||||||
|
````typescript
|
||||||
|
/**
|
||||||
|
* Creates a new model instance with the provided data.
|
||||||
|
*
|
||||||
|
* @template T - The model type extending BaseModel
|
||||||
|
* @param data - The data to create the model with
|
||||||
|
* @param options - Optional creation options
|
||||||
|
* @returns Promise resolving to the created model instance
|
||||||
|
*
|
||||||
|
* @throws {ValidationError} When data validation fails
|
||||||
|
* @throws {DatabaseError} When database operation fails
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const user = await User.create({
|
||||||
|
* username: 'john',
|
||||||
|
* email: 'john@example.com'
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
static async create<T extends BaseModel>(
|
||||||
|
this: ModelConstructor<T>,
|
||||||
|
data: Partial<T>,
|
||||||
|
options?: CreateOptions
|
||||||
|
): Promise<T> {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
### Code Comments
|
||||||
|
|
||||||
|
Add comments for complex logic:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Explaining complex logic
|
||||||
|
private calculateShardIndex(key: string, shardCount: number): number {
|
||||||
|
// Use consistent hashing to distribute data evenly across shards
|
||||||
|
// This ensures that the same key always maps to the same shard
|
||||||
|
const hash = this.hashFunction(key);
|
||||||
|
|
||||||
|
// Use modulo to map hash to shard index
|
||||||
|
// Add 1 to avoid negative numbers with certain hash functions
|
||||||
|
return Math.abs(hash) % shardCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Good - Explaining business logic
|
||||||
|
async ensureUserDatabaseExists(userId: string): Promise<Database> {
|
||||||
|
// Check if user database already exists in cache
|
||||||
|
const existingDb = this.userDatabases.get(userId);
|
||||||
|
if (existingDb) {
|
||||||
|
return existingDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new user database with user-specific configuration
|
||||||
|
// This provides data isolation and improved performance
|
||||||
|
const database = await this.createUserDatabase(userId);
|
||||||
|
|
||||||
|
// Cache the database for future use
|
||||||
|
this.userDatabases.set(userId, database);
|
||||||
|
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚡ Performance Monitoring
|
||||||
|
|
||||||
|
### Metrics Collection
|
||||||
|
|
||||||
|
Add metrics to important operations:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Performance monitoring
|
||||||
|
export class QueryExecutor {
|
||||||
|
private metrics = new Map<string, PerformanceMetric>();
|
||||||
|
|
||||||
|
async executeQuery<T>(query: QueryBuilder<T>): Promise<QueryResult<T>> {
|
||||||
|
const startTime = Date.now();
|
||||||
|
const queryKey = query.toString();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await this.internalExecuteQuery(query);
|
||||||
|
|
||||||
|
// Record successful execution
|
||||||
|
this.recordMetric(queryKey, Date.now() - startTime, true);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
// Record failed execution
|
||||||
|
this.recordMetric(queryKey, Date.now() - startTime, false);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private recordMetric(queryKey: string, duration: number, success: boolean): void {
|
||||||
|
const existing = this.metrics.get(queryKey) || {
|
||||||
|
count: 0,
|
||||||
|
totalDuration: 0,
|
||||||
|
successCount: 0,
|
||||||
|
averageDuration: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
existing.count++;
|
||||||
|
existing.totalDuration += duration;
|
||||||
|
if (success) existing.successCount++;
|
||||||
|
existing.averageDuration = existing.totalDuration / existing.count;
|
||||||
|
|
||||||
|
this.metrics.set(queryKey, existing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 Security Considerations
|
||||||
|
|
||||||
|
### Input Validation
|
||||||
|
|
||||||
|
Validate all inputs thoroughly:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Input validation
|
||||||
|
export class UserService {
|
||||||
|
async createUser(userData: UserCreateData): Promise<User> {
|
||||||
|
// Validate required fields
|
||||||
|
if (!userData.username || typeof userData.username !== 'string') {
|
||||||
|
throw new ValidationError('username', userData.username, 'required string');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize username
|
||||||
|
const sanitizedUsername = userData.username.trim().toLowerCase();
|
||||||
|
|
||||||
|
// Check length constraints
|
||||||
|
if (sanitizedUsername.length < 3 || sanitizedUsername.length > 20) {
|
||||||
|
throw new ValidationError('username', sanitizedUsername, 'length between 3-20');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for valid characters
|
||||||
|
if (!/^[a-zA-Z0-9_]+$/.test(sanitizedUsername)) {
|
||||||
|
throw new ValidationError('username', sanitizedUsername, 'alphanumeric and underscore only');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check uniqueness
|
||||||
|
const existingUser = await User.findOne({ username: sanitizedUsername });
|
||||||
|
if (existingUser) {
|
||||||
|
throw new ConflictError('Username already exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
return User.create({
|
||||||
|
...userData,
|
||||||
|
username: sanitizedUsername,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Information
|
||||||
|
|
||||||
|
Don't leak sensitive information in errors:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Good - Safe error messages
|
||||||
|
catch (error) {
|
||||||
|
if (error instanceof DatabaseConnectionError) {
|
||||||
|
// Don't expose internal connection details
|
||||||
|
throw new OperationError(
|
||||||
|
'Database operation failed',
|
||||||
|
'DATABASE_ERROR',
|
||||||
|
{ operation: 'create_user' } // Safe context only
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Bad - Leaking sensitive info
|
||||||
|
catch (error) {
|
||||||
|
throw new Error(`Database connection failed: ${error.message} at ${error.stack}`);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
These guidelines help ensure that DebrosFramework maintains high code quality, performance, and developer experience. When in doubt, prioritize clarity, type safety, and developer experience.
|
||||||
|
|
||||||
|
**Next:** Check out our [Testing Guide](./testing-guide) to learn about writing comprehensive tests.
|
475
docs/docs/contributing/development-setup.md
Normal file
475
docs/docs/contributing/development-setup.md
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Development Setup
|
||||||
|
|
||||||
|
This guide will help you set up your development environment for contributing to DebrosFramework.
|
||||||
|
|
||||||
|
## 🔧 Prerequisites
|
||||||
|
|
||||||
|
### Required Software
|
||||||
|
|
||||||
|
| Software | Version | Purpose |
|
||||||
|
| -------------- | ------- | --------------------------- |
|
||||||
|
| **Node.js** | 18.0+ | Runtime environment |
|
||||||
|
| **pnpm** | Latest | Package manager (preferred) |
|
||||||
|
| **Git** | Latest | Version control |
|
||||||
|
| **Docker** | Latest | Integration testing |
|
||||||
|
| **TypeScript** | 5.0+ | Development language |
|
||||||
|
|
||||||
|
### Optional Tools
|
||||||
|
|
||||||
|
- **VS Code** - Recommended editor with excellent TypeScript support
|
||||||
|
- **Docker Desktop** - GUI for Docker management
|
||||||
|
- **Gitea CLI** (if available) - Command-line interface for our Gitea instance
|
||||||
|
|
||||||
|
## 🚀 Environment Setup
|
||||||
|
|
||||||
|
### 1. Repository Access
|
||||||
|
|
||||||
|
#### Create Gitea Account
|
||||||
|
|
||||||
|
1. Visit https://git.debros.io
|
||||||
|
2. Click "Sign Up" to create an account
|
||||||
|
3. Verify your email address
|
||||||
|
4. Request access to the DeBros organization (contact maintainers)
|
||||||
|
|
||||||
|
#### Fork and Clone
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fork the repository through Gitea web interface
|
||||||
|
# Then clone your fork
|
||||||
|
git clone https://git.debros.io/DeBros/network.git
|
||||||
|
cd network
|
||||||
|
|
||||||
|
# Add upstream remote
|
||||||
|
git remote add upstream https://git.debros.io/DeBros/network.git
|
||||||
|
|
||||||
|
# Verify remotes
|
||||||
|
git remote -v
|
||||||
|
# origin https://git.debros.io/DeBros/network.git (fetch)
|
||||||
|
# origin https://git.debros.io/DeBros/network.git (push)
|
||||||
|
# upstream https://git.debros.io/DeBros/network.git (fetch)
|
||||||
|
# upstream https://git.debros.io/DeBros/network.git (push)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Project Setup
|
||||||
|
|
||||||
|
#### Install Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install pnpm if not already installed
|
||||||
|
npm install -g pnpm
|
||||||
|
|
||||||
|
# Install project dependencies
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Install global development tools
|
||||||
|
pnpm install -g tsx ts-node
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Verify Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check versions
|
||||||
|
node --version # Should be 18.0+
|
||||||
|
pnpm --version # Should be latest
|
||||||
|
tsc --version # Should be 5.0+
|
||||||
|
|
||||||
|
# Check project setup
|
||||||
|
pnpm run build # Should complete without errors
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. IDE Configuration
|
||||||
|
|
||||||
|
#### VS Code Setup
|
||||||
|
|
||||||
|
Install recommended extensions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install VS Code extensions
|
||||||
|
code --install-extension ms-vscode.vscode-typescript-next
|
||||||
|
code --install-extension esbenp.prettier-vscode
|
||||||
|
code --install-extension ms-vscode.vscode-eslint
|
||||||
|
code --install-extension bradlc.vscode-tailwindcss
|
||||||
|
code --install-extension ms-vscode.vscode-json
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `.vscode/settings.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"typescript.preferences.includePackageJsonAutoImports": "auto",
|
||||||
|
"typescript.suggest.autoImports": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"typescript.preferences.importModuleSpecifier": "relative",
|
||||||
|
"files.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/dist": true,
|
||||||
|
"**/.git": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### TypeScript Configuration
|
||||||
|
|
||||||
|
The project includes proper TypeScript configuration in `tsconfig.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 Development Workflow
|
||||||
|
|
||||||
|
### Running the Framework
|
||||||
|
|
||||||
|
#### Basic Build and Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clean build
|
||||||
|
pnpm run clean
|
||||||
|
pnpm run build
|
||||||
|
|
||||||
|
# Run unit tests
|
||||||
|
pnpm run test:unit
|
||||||
|
|
||||||
|
# Run integration tests (requires Docker)
|
||||||
|
pnpm run test:real
|
||||||
|
|
||||||
|
# Run specific blog integration test
|
||||||
|
pnpm run test:blog-integration
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Watch mode for development
|
||||||
|
pnpm run dev
|
||||||
|
|
||||||
|
# Linting and formatting
|
||||||
|
pnpm run lint # Check for lint errors
|
||||||
|
pnpm run lint:fix # Fix auto-fixable lint errors
|
||||||
|
pnpm run format # Format code with Prettier
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
pnpm run clean # Remove build artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing Setup
|
||||||
|
|
||||||
|
#### Unit Tests
|
||||||
|
|
||||||
|
Unit tests use Jest and are located in `tests/unit/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all unit tests
|
||||||
|
pnpm run test:unit
|
||||||
|
|
||||||
|
# Run specific test file
|
||||||
|
npx jest tests/unit/framework/core/ConfigManager.test.ts
|
||||||
|
|
||||||
|
# Run tests in watch mode
|
||||||
|
npx jest --watch tests/unit/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Integration Tests
|
||||||
|
|
||||||
|
Integration tests use Docker to create real IPFS/OrbitDB environments:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ensure Docker is running
|
||||||
|
docker --version
|
||||||
|
|
||||||
|
# Run full integration test suite
|
||||||
|
pnpm run test:real
|
||||||
|
|
||||||
|
# This will:
|
||||||
|
# 1. Build Docker containers
|
||||||
|
# 2. Start IPFS bootstrap node
|
||||||
|
# 3. Start multiple framework instances
|
||||||
|
# 4. Run real-world scenarios
|
||||||
|
# 5. Tear down containers
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Test Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
tests/
|
||||||
|
├── unit/ # Unit tests
|
||||||
|
│ ├── framework/ # Framework component tests
|
||||||
|
│ └── shared/ # Shared test utilities
|
||||||
|
└── real-integration/ # Integration tests
|
||||||
|
└── blog-scenario/ # Blog application test scenario
|
||||||
|
├── docker/ # Docker configuration
|
||||||
|
├── scenarios/ # Test scenarios
|
||||||
|
└── models/ # Test models
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Development
|
||||||
|
|
||||||
|
#### Docker Setup for Testing
|
||||||
|
|
||||||
|
The integration tests require Docker. Make sure you have:
|
||||||
|
|
||||||
|
1. **Docker Desktop** installed and running
|
||||||
|
2. **Docker Compose** available (included with Docker Desktop)
|
||||||
|
3. **Sufficient memory** allocated to Docker (4GB+ recommended)
|
||||||
|
|
||||||
|
#### Docker Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build test containers
|
||||||
|
docker-compose -f tests/real-integration/blog-scenario/docker/docker-compose.blog.yml build
|
||||||
|
|
||||||
|
# Run integration tests
|
||||||
|
pnpm run test:real
|
||||||
|
|
||||||
|
# Clean up Docker resources
|
||||||
|
docker system prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Git Workflow
|
||||||
|
|
||||||
|
### Branch Strategy
|
||||||
|
|
||||||
|
We use a feature branch workflow:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start from main branch
|
||||||
|
git checkout main
|
||||||
|
git pull upstream main
|
||||||
|
|
||||||
|
# Create feature branch
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
|
||||||
|
# Make changes, commit, and push
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: add new feature"
|
||||||
|
git push origin feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pull Request Process
|
||||||
|
|
||||||
|
1. **Create Pull Request** in Gitea web interface
|
||||||
|
2. **Fill out template** with description and testing notes
|
||||||
|
3. **Request review** from maintainers
|
||||||
|
4. **Address feedback** if any
|
||||||
|
5. **Merge** once approved
|
||||||
|
|
||||||
|
## 🛠️ Development Tools
|
||||||
|
|
||||||
|
### Code Quality Tools
|
||||||
|
|
||||||
|
#### ESLint Configuration
|
||||||
|
|
||||||
|
The project uses ESLint for code quality:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check for issues
|
||||||
|
pnpm run lint
|
||||||
|
|
||||||
|
# Fix auto-fixable issues
|
||||||
|
pnpm run lint:fix
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Prettier Configuration
|
||||||
|
|
||||||
|
Prettier handles code formatting:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format all files
|
||||||
|
pnpm run format
|
||||||
|
|
||||||
|
# Format specific files
|
||||||
|
npx prettier --write "src/**/*.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Husky Git Hooks
|
||||||
|
|
||||||
|
The project includes pre-commit hooks:
|
||||||
|
|
||||||
|
- **Pre-commit**: Runs lint-staged to format staged files
|
||||||
|
- **Pre-push**: Runs basic tests to prevent broken code
|
||||||
|
|
||||||
|
### Package Scripts Reference
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && tsc-esm-fix --outDir=./dist/esm",
|
||||||
|
"dev": "tsc -w",
|
||||||
|
"clean": "rimraf dist",
|
||||||
|
"lint": "npx eslint src",
|
||||||
|
"format": "prettier --write \"**/*.{ts,js,json,md}\"",
|
||||||
|
"lint:fix": "npx eslint src --fix",
|
||||||
|
"test:unit": "jest tests/unit",
|
||||||
|
"test:blog-integration": "tsx tests/real-integration/blog-scenario/scenarios/BlogTestRunner.ts",
|
||||||
|
"test:real": "docker-compose -f tests/real-integration/blog-scenario/docker/docker-compose.blog.yml up --build --abort-on-container-exit",
|
||||||
|
"prepublishOnly": "npm run clean && npm run build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Debugging
|
||||||
|
|
||||||
|
### Framework Debugging
|
||||||
|
|
||||||
|
#### Enable Debug Logging
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// In your test or development code
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
monitoring: {
|
||||||
|
logLevel: 'debug',
|
||||||
|
enableMetrics: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### VS Code Debugging
|
||||||
|
|
||||||
|
Create `.vscode/launch.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug Unit Tests",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
||||||
|
"args": ["--runInBand", "${file}"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"internalConsoleOptions": "neverOpen",
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug Integration Test",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/tsx",
|
||||||
|
"args": ["tests/real-integration/blog-scenario/scenarios/BlogTestRunner.ts"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Node.js Version Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check Node.js version
|
||||||
|
node --version
|
||||||
|
|
||||||
|
# If using nvm, switch to correct version
|
||||||
|
nvm use 18
|
||||||
|
nvm install 18.19.0
|
||||||
|
nvm alias default 18.19.0
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Docker Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check Docker status
|
||||||
|
docker --version
|
||||||
|
docker-compose --version
|
||||||
|
|
||||||
|
# Clean Docker cache if tests fail
|
||||||
|
docker system prune -f
|
||||||
|
docker volume prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
#### TypeScript Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clear TypeScript cache
|
||||||
|
npx tsc --build --clean
|
||||||
|
|
||||||
|
# Rebuild project
|
||||||
|
pnpm run clean
|
||||||
|
pnpm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Additional Resources
|
||||||
|
|
||||||
|
### Learning Resources
|
||||||
|
|
||||||
|
- **[IPFS Documentation](https://docs.ipfs.io/)** - Understanding IPFS concepts
|
||||||
|
- **[OrbitDB Guide](https://orbitdb.org/getting-started/)** - OrbitDB basics
|
||||||
|
- **[libp2p Concepts](https://docs.libp2p.io/concepts/)** - Peer-to-peer networking
|
||||||
|
- **[TypeScript Handbook](https://www.typescriptlang.org/docs/)** - TypeScript reference
|
||||||
|
|
||||||
|
### Community Resources
|
||||||
|
|
||||||
|
- **Gitea Repository**: https://git.debros.io/DeBros/network
|
||||||
|
- **Documentation**: This documentation site
|
||||||
|
- **Discord** (if available): Community chat
|
||||||
|
- **Email**: Contact maintainers for access and questions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Setup Verification
|
||||||
|
|
||||||
|
Run this checklist to verify your setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Check Node.js version
|
||||||
|
node --version # Should be 18.0+
|
||||||
|
|
||||||
|
# 2. Check package manager
|
||||||
|
pnpm --version # Should be latest
|
||||||
|
|
||||||
|
# 3. Install dependencies
|
||||||
|
pnpm install # Should complete without errors
|
||||||
|
|
||||||
|
# 4. Build project
|
||||||
|
pnpm run build # Should complete without errors
|
||||||
|
|
||||||
|
# 5. Run linting
|
||||||
|
pnpm run lint # Should pass with no errors
|
||||||
|
|
||||||
|
# 6. Run unit tests
|
||||||
|
pnpm run test:unit # Should pass all tests
|
||||||
|
|
||||||
|
# 7. Check Docker (optional, for integration tests)
|
||||||
|
docker --version # Should show Docker version
|
||||||
|
pnpm run test:real # Should run integration tests
|
||||||
|
```
|
||||||
|
|
||||||
|
If all steps pass, you're ready to contribute! 🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Next Steps:**
|
||||||
|
|
||||||
|
- Read our **[Code Guidelines](./code-guidelines)** to understand coding standards
|
||||||
|
- Check out **[Testing Guide](./testing-guide)** to learn about writing tests
|
||||||
|
- Browse existing issues in Gitea to find something to work on
|
214
docs/docs/contributing/overview.md
Normal file
214
docs/docs/contributing/overview.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# Contributing to DebrosFramework
|
||||||
|
|
||||||
|
Welcome to the DebrosFramework contributor community! We're excited to have you help build the future of decentralized application development.
|
||||||
|
|
||||||
|
## 🌟 Why Contribute?
|
||||||
|
|
||||||
|
DebrosFramework is an ambitious project that aims to make decentralized application development as simple as traditional web development. Your contributions help:
|
||||||
|
|
||||||
|
- **Advance decentralized technology** - Make dApps more accessible to developers
|
||||||
|
- **Build better tools** - Create powerful abstractions over IPFS and OrbitDB
|
||||||
|
- **Shape the future** - Influence how decentralized applications are built
|
||||||
|
- **Learn cutting-edge tech** - Work with the latest in distributed systems
|
||||||
|
- **Join a community** - Connect with like-minded developers
|
||||||
|
|
||||||
|
## 🚀 Development Status
|
||||||
|
|
||||||
|
**Current Version**: 0.5.0-beta
|
||||||
|
**Status**: Active Development - Beta Release
|
||||||
|
|
||||||
|
DebrosFramework is in active beta development. The core architecture is not stable, but we're continuously improving APIs, adding features, and optimizing performance. This is an excellent time to contribute as your input can significantly shape the framework's direction.
|
||||||
|
|
||||||
|
### What's Ready for Contribution
|
||||||
|
|
||||||
|
✅ **Core Framework** - Stable architecture, ready for enhancements
|
||||||
|
✅ **Model System** - Decorator-based models with validation
|
||||||
|
✅ **Query Builder** - Rich querying with optimization
|
||||||
|
✅ **Relationship System** - Complex data relationships
|
||||||
|
✅ **Sharding** - Automatic data distribution
|
||||||
|
✅ **Migration System** - Schema evolution tools
|
||||||
|
✅ **Documentation** - Comprehensive guides and examples
|
||||||
|
|
||||||
|
### What's Coming Next
|
||||||
|
|
||||||
|
🔄 **Performance Optimization** - Query caching and execution improvements
|
||||||
|
🔄 **Advanced Features** - Real-time subscriptions and event systems
|
||||||
|
🔄 **Developer Experience** - Better tooling and debugging
|
||||||
|
🔄 **Production Ready** - Stability and performance for production use
|
||||||
|
|
||||||
|
## 🏗️ Repository Information
|
||||||
|
|
||||||
|
### Self-Hosted Git Repository
|
||||||
|
|
||||||
|
We use a **self-hosted Gitea instance** instead of GitHub:
|
||||||
|
|
||||||
|
**Repository URL**: https://git.debros.io/DeBros/network
|
||||||
|
|
||||||
|
**Why Gitea?**
|
||||||
|
|
||||||
|
- **Decentralization aligned** - Fits our philosophy of decentralized systems
|
||||||
|
- **Full control** - Complete control over our development infrastructure
|
||||||
|
- **Privacy focused** - No external dependencies for sensitive development data
|
||||||
|
- **Community owned** - Aligns with our open-source, community-driven approach
|
||||||
|
|
||||||
|
### Getting Repository Access
|
||||||
|
|
||||||
|
1. **Create an account** at https://git.debros.io
|
||||||
|
2. **Request access** by contacting the maintainers
|
||||||
|
3. **Fork the repository** to your account
|
||||||
|
4. **Clone your fork** locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.debros.io/DeBros/network.git
|
||||||
|
cd network
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 How to Contribute
|
||||||
|
|
||||||
|
### Types of Contributions Welcome
|
||||||
|
|
||||||
|
| Type | Description | Skill Level | Time Commitment |
|
||||||
|
| ----------------------- | ------------------------------ | --------------------- | --------------- |
|
||||||
|
| 🐛 **Bug Reports** | Find and report issues | Beginner | Low |
|
||||||
|
| 📖 **Documentation** | Improve guides and examples | Beginner-Intermediate | Low-Medium |
|
||||||
|
| ✨ **Feature Requests** | Suggest new capabilities | Any | Low |
|
||||||
|
| 🧪 **Testing** | Write tests and test scenarios | Intermediate | Medium |
|
||||||
|
| 🔧 **Bug Fixes** | Fix reported issues | Intermediate | Medium |
|
||||||
|
| ⚡ **Performance** | Optimize existing code | Advanced | Medium-High |
|
||||||
|
| 🚀 **New Features** | Implement new functionality | Advanced | High |
|
||||||
|
| 🏗️ **Architecture** | Design system improvements | Expert | High |
|
||||||
|
|
||||||
|
### Contribution Areas
|
||||||
|
|
||||||
|
#### 🎯 High Priority Areas
|
||||||
|
|
||||||
|
1. **Integration Tests** - Real-world scenario testing
|
||||||
|
2. **Performance Optimization** - Query execution and caching
|
||||||
|
3. **Developer Experience** - Better error messages and debugging
|
||||||
|
4. **Documentation** - More examples and use cases
|
||||||
|
5. **Type Safety** - Improved TypeScript definitions
|
||||||
|
|
||||||
|
#### 🔥 Hot Topics
|
||||||
|
|
||||||
|
- **Real-time Features** - PubSub improvements and real-time data sync
|
||||||
|
- **Migration Tools** - Better schema evolution and data transformation
|
||||||
|
- **Query Optimization** - Smarter query planning and execution
|
||||||
|
- **Monitoring** - Performance metrics and health checking
|
||||||
|
- **CLI Tools** - Development and deployment tooling
|
||||||
|
|
||||||
|
## 🛠️ Technical Overview
|
||||||
|
|
||||||
|
### Architecture Understanding
|
||||||
|
|
||||||
|
Before contributing code, familiarize yourself with the framework architecture:
|
||||||
|
|
||||||
|
```
|
||||||
|
DebrosFramework/
|
||||||
|
├── Core Layer (ConfigManager, DatabaseManager)
|
||||||
|
├── Model Layer (BaseModel, Decorators, Validation)
|
||||||
|
├── Query Layer (QueryBuilder, QueryExecutor, Optimization)
|
||||||
|
├── Relationship Layer (RelationshipManager, LazyLoader)
|
||||||
|
├── Sharding Layer (ShardManager, Distribution)
|
||||||
|
├── Migration Layer (MigrationManager, MigrationBuilder)
|
||||||
|
├── Feature Layer (PinningManager, PubSubManager)
|
||||||
|
└── Service Layer (OrbitDBService, IPFSService)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Technologies
|
||||||
|
|
||||||
|
- **TypeScript** - Primary development language
|
||||||
|
- **OrbitDB** - Distributed database layer
|
||||||
|
- **IPFS/Helia** - Distributed storage layer
|
||||||
|
- **libp2p** - Peer-to-peer networking
|
||||||
|
- **Docker** - Containerization for testing
|
||||||
|
- **Jest** - Unit testing framework
|
||||||
|
- **Prettier/ESLint** - Code formatting and linting
|
||||||
|
|
||||||
|
### Development Philosophy
|
||||||
|
|
||||||
|
1. **Developer Experience First** - APIs should be intuitive and well-documented
|
||||||
|
2. **Type Safety** - Comprehensive TypeScript support throughout
|
||||||
|
3. **Performance by Default** - Optimize common use cases automatically
|
||||||
|
4. **Flexibility** - Support diverse application patterns
|
||||||
|
5. **Reliability** - Robust error handling and recovery
|
||||||
|
6. **Scalability** - Design for applications with millions of users
|
||||||
|
|
||||||
|
## 📋 Getting Started Checklist
|
||||||
|
|
||||||
|
Before making your first contribution:
|
||||||
|
|
||||||
|
- [ ] Read this contributor guide completely
|
||||||
|
- [ ] Set up your development environment
|
||||||
|
- [ ] Run the test suite successfully
|
||||||
|
- [ ] Explore the codebase and documentation
|
||||||
|
- [ ] Join our community channels
|
||||||
|
- [ ] Choose your first contribution area
|
||||||
|
- [ ] Check existing issues and discussions
|
||||||
|
|
||||||
|
## 🔗 Quick Links
|
||||||
|
|
||||||
|
- **[Development Setup](./development-setup)** - Get your environment ready
|
||||||
|
- **[Code Guidelines](./code-guidelines)** - Coding standards and best practices
|
||||||
|
- **[Testing Guide](./testing-guide)** - How to write and run tests
|
||||||
|
- **[Documentation Guide](./documentation-guide)** - Contributing to docs
|
||||||
|
- **[Release Process](./release-process)** - How we ship new versions
|
||||||
|
- **[Community](./community)** - Connect with other contributors
|
||||||
|
|
||||||
|
## 💡 First Time Contributors
|
||||||
|
|
||||||
|
New to open source or DebrosFramework? Start here:
|
||||||
|
|
||||||
|
1. **Good First Issues** - Look for issues tagged `good-first-issue` in our Gitea repository
|
||||||
|
2. **Documentation** - Help improve our guides and examples
|
||||||
|
3. **Testing** - Add test cases for existing functionality
|
||||||
|
4. **Examples** - Create new usage examples and tutorials
|
||||||
|
|
||||||
|
## 🎯 Contributor Levels
|
||||||
|
|
||||||
|
### 🌱 **Beginner Contributors**
|
||||||
|
|
||||||
|
- Report bugs and suggest improvements
|
||||||
|
- Fix typos and improve documentation
|
||||||
|
- Add simple test cases
|
||||||
|
- Create usage examples
|
||||||
|
|
||||||
|
### 🌿 **Intermediate Contributors**
|
||||||
|
|
||||||
|
- Fix bugs and implement small features
|
||||||
|
- Improve existing functionality
|
||||||
|
- Write comprehensive tests
|
||||||
|
- Contribute to API design discussions
|
||||||
|
|
||||||
|
### 🌳 **Advanced Contributors**
|
||||||
|
|
||||||
|
- Implement major features
|
||||||
|
- Optimize performance-critical code
|
||||||
|
- Design architectural improvements
|
||||||
|
- Mentor other contributors
|
||||||
|
|
||||||
|
### 🏆 **Core Contributors**
|
||||||
|
|
||||||
|
- Drive technical direction
|
||||||
|
- Review and merge contributions
|
||||||
|
- Manage releases and roadmap
|
||||||
|
- Represent the project publicly
|
||||||
|
|
||||||
|
## 🏅 Recognition
|
||||||
|
|
||||||
|
Contributors are recognized through:
|
||||||
|
|
||||||
|
- **Contributor list** in repository and documentation
|
||||||
|
- **Release notes** crediting significant contributions
|
||||||
|
- **Community highlights** in announcements
|
||||||
|
- **Direct contributor access** for consistent contributors
|
||||||
|
- **Maintainer status** for exceptional long-term contributors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Ready to contribute? Head over to our **[Development Setup Guide](./development-setup)** to get started!
|
||||||
|
|
||||||
|
_Have questions? Join our community channels or reach out to the maintainers. We're here to help! 🚀_
|
@ -109,6 +109,18 @@ DebrosFramework is perfect for developers who want to:
|
|||||||
|
|
||||||
Ready to build your first decentralized application? Check out our [Getting Started Guide](./getting-started) to set up your development environment and create your first models.
|
Ready to build your first decentralized application? Check out our [Getting Started Guide](./getting-started) to set up your development environment and create your first models.
|
||||||
|
|
||||||
|
## Development Status
|
||||||
|
|
||||||
|
**Current Version**: 0.5.0-beta
|
||||||
|
**Status**: Active Development - Beta Release
|
||||||
|
|
||||||
|
DebrosFramework is currently in beta and under active development. The core architecture and APIs are stabilizing, but some features may still change. We recommend using it for:
|
||||||
|
|
||||||
|
- ✅ **Development and Testing**: Perfect for building and testing decentralized applications
|
||||||
|
- ✅ **Prototyping**: Rapid prototyping of dApp concepts
|
||||||
|
- ✅ **Learning**: Understanding decentralized application architecture
|
||||||
|
- ⚠️ **Production**: Use with caution - APIs may change in future versions
|
||||||
|
|
||||||
## Community and Support
|
## Community and Support
|
||||||
|
|
||||||
- 📖 [Documentation](./getting-started) - Comprehensive guides and examples
|
- 📖 [Documentation](./getting-started) - Comprehensive guides and examples
|
||||||
|
@ -40,6 +40,15 @@ const sidebars: SidebarsConfig = {
|
|||||||
'examples/basic-usage',
|
'examples/basic-usage',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Contributing',
|
||||||
|
items: [
|
||||||
|
'contributing/overview',
|
||||||
|
'contributing/development-setup',
|
||||||
|
'contributing/code-guidelines',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
// API Reference sidebar
|
// API Reference sidebar
|
||||||
|
17
package.json
17
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@debros/network",
|
"name": "@debros/network",
|
||||||
"version": "0.5.0-beta",
|
"version": "0.5.0-beta",
|
||||||
"description": "Debros network core functionality for IPFS, libp2p and OrbitDB",
|
"description": "DebrosFramework - A powerful Node.js framework providing ORM-like abstraction over OrbitDB and IPFS for building scalable decentralized applications",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
@ -24,12 +24,19 @@
|
|||||||
"test:real": "docker-compose -f tests/real-integration/blog-scenario/docker/docker-compose.blog.yml up --build --abort-on-container-exit"
|
"test:real": "docker-compose -f tests/real-integration/blog-scenario/docker/docker-compose.blog.yml up --build --abort-on-container-exit"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ipfs",
|
"debros",
|
||||||
"libp2p",
|
"framework",
|
||||||
"orbitdb",
|
"orm",
|
||||||
"decentralized",
|
"decentralized",
|
||||||
|
"ipfs",
|
||||||
|
"orbitdb",
|
||||||
"p2p",
|
"p2p",
|
||||||
"debros"
|
"typescript",
|
||||||
|
"models",
|
||||||
|
"query-builder",
|
||||||
|
"sharding",
|
||||||
|
"dapp",
|
||||||
|
"distributed"
|
||||||
],
|
],
|
||||||
"author": "Debros",
|
"author": "Debros",
|
||||||
"license": "gnu-gpl-v3.0",
|
"license": "gnu-gpl-v3.0",
|
||||||
|
@ -132,7 +132,7 @@ export class DebrosFramework {
|
|||||||
this.status = {
|
this.status = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
healthy: false,
|
healthy: false,
|
||||||
version: '1.0.0', // This would come from package.json
|
version: '0.5.0-beta', // This would come from package.json
|
||||||
environment: this.config.environment || 'development',
|
environment: this.config.environment || 'development',
|
||||||
services: {
|
services: {
|
||||||
orbitdb: 'disconnected',
|
orbitdb: 'disconnected',
|
||||||
@ -523,8 +523,7 @@ export class DebrosFramework {
|
|||||||
|
|
||||||
// Overall health check - only require core services to be healthy
|
// Overall health check - only require core services to be healthy
|
||||||
const coreServicesHealthy =
|
const coreServicesHealthy =
|
||||||
this.status.services.orbitdb === 'connected' &&
|
this.status.services.orbitdb === 'connected' && this.status.services.ipfs === 'connected';
|
||||||
this.status.services.ipfs === 'connected';
|
|
||||||
|
|
||||||
this.status.healthy = this.initialized && coreServicesHealthy;
|
this.status.healthy = this.initialized && coreServicesHealthy;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -616,7 +615,7 @@ export class DebrosFramework {
|
|||||||
return {
|
return {
|
||||||
healthy: this.status.healthy,
|
healthy: this.status.healthy,
|
||||||
services: { ...this.status.services },
|
services: { ...this.status.services },
|
||||||
lastCheck: this.status.lastHealthCheck
|
lastCheck: this.status.lastHealthCheck,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,8 +78,8 @@ export type { FieldConfig, RelationshipConfig, ModelConfig, ValidationError } fr
|
|||||||
// export { ValidationError } from './types/models'; // Already exported above
|
// export { ValidationError } from './types/models'; // Already exported above
|
||||||
|
|
||||||
// Version information
|
// Version information
|
||||||
export const FRAMEWORK_VERSION = '1.0.0';
|
export const FRAMEWORK_VERSION = '0.5.0-beta';
|
||||||
export const API_VERSION = '1.0';
|
export const API_VERSION = '0.5';
|
||||||
|
|
||||||
// Feature flags for conditional exports
|
// Feature flags for conditional exports
|
||||||
export const FEATURES = {
|
export const FEATURES = {
|
||||||
|
Reference in New Issue
Block a user