Contributing to Bindra
Thank you for your interest in contributing to Bindra! We welcome contributions from the community.
📋 Table of Contents
- Code of Conduct
- Getting Started
- Development Setup
- How to Contribute
- Coding Standards
- Testing Guidelines
- Pull Request Process
- Documentation
📜 Code of Conduct
Our Pledge
We are committed to providing a welcoming and inclusive environment for everyone. We expect all contributors to:
- Be respectful and considerate
- Welcome newcomers and help them get started
- Accept constructive criticism gracefully
- Focus on what's best for the community
- Show empathy toward other community members
Unacceptable Behavior
- Harassment, discrimination, or offensive comments
- Trolling, insulting, or derogatory remarks
- Personal or political attacks
- Publishing others' private information
- Any conduct that could reasonably be considered inappropriate
🚀 Getting Started
Prerequisites
- Node.js 16+ - Download
- pnpm - Install with
npm install -g pnpm - Git - Download
- TypeScript - Familiarity recommended
Quick Start
bash
# 1. Fork the repository on GitHub
# Click the "Fork" button at https://github.com/mohamad-j/Bindra
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/Bindra.git
cd Bindra
# 3. Add upstream remote
git remote add upstream https://github.com/mohamad-j/Bindra.git
# 4. Install dependencies
pnpm install
# 5. Run tests
pnpm test
# 6. Build the project
pnpm build🛠️ Development Setup
Project Structure
Bindra/
├── src/
│ ├── core/ # Core classes (DataSource, Container, etc.)
│ ├── utils/ # Utility functions
│ └── index.ts # Main entry point
├── test/ # Test files
├── examples/ # Example implementations
├── docs/ # Documentation
├── dist/ # Build output (generated)
└── package.jsonAvailable Scripts
bash
# Development
pnpm dev # Watch mode with auto-rebuild
# Testing
pnpm test # Run all tests
pnpm test:watch # Run tests in watch mode
pnpm test:ui # Run tests with UI
pnpm test:coverage # Generate coverage report
# Building
pnpm build # Build for production
pnpm typecheck # Check TypeScript types
# Linting (if configured)
pnpm lint # Lint code
pnpm lint:fix # Fix linting issuesEditor Setup
VS Code (Recommended)
Install these extensions:
- TypeScript - Built-in
- ESLint - For linting
- Prettier - For formatting
- Vitest - For running tests
Settings
Create .vscode/settings.json:
json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}🤝 How to Contribute
Types of Contributions
We welcome various types of contributions:
- Bug Fixes - Fix issues or bugs
- Features - Add new functionality
- Documentation - Improve or add docs
- Examples - Create usage examples
- Tests - Add or improve tests
- Performance - Optimize existing code
- Refactoring - Improve code quality
Finding Something to Work On
- Check Issues - Look for issues labeled
good first issueorhelp wanted - Browse Discussions - See what features are being discussed
- Fix Bugs - Found a bug? Fix it and submit a PR
- Improve Docs - Documentation can always be better
Before You Start
- Check existing issues - Avoid duplicate work
- Open an issue - Discuss your idea before major changes
- Get feedback - Ask questions in discussions
- Read guidelines - Follow these contribution guidelines
📝 Coding Standards
TypeScript Guidelines
Use Strict Mode
typescript
// ✅ Good - Strict TypeScript
interface User {
id: number;
name: string;
email?: string;
}
function getUser(id: number): User | null {
// ...
}typescript
// ❌ Bad - Using any
function getUser(id: any): any {
// ...
}Generic Type Parameters
typescript
// ✅ Good - Generic with constraints
export class DataSource<T extends Record<string, any>> {
private data: T[] | null = null;
async create(record: Partial<T>): Promise<T> {
// ...
}
}Explicit Return Types
typescript
// ✅ Good - Explicit return type
async function fetchUsers(): Promise<User[]> {
// ...
}
// ❌ Bad - Implicit return type
async function fetchUsers() {
// ...
}Code Style
Naming Conventions
typescript
// Classes: PascalCase
class DataSource<T> {}
// Interfaces: PascalCase
interface DataSourceConfig {}
// Functions: camelCase
function fetchData() {}
// Constants: UPPER_SNAKE_CASE
const MAX_RETRY_ATTEMPTS = 3;
// Private properties: camelCase with underscore prefix (optional)
class Example {
private _internalState: string;
}File Naming
- Classes:
DataSource.ts,Container.ts - Utilities:
performance.ts,validation.ts - Tests:
DataSource.test.ts,Container.test.ts - Types:
types.ts,interfaces.ts
Comments and Documentation
JSDoc for Public APIs
typescript
/**
* Creates a new record in the data source.
*
* @param record - The record to create (partial object)
* @returns Promise resolving to the created record
* @throws {ValidationError} If validation fails
* @throws {NetworkError} If the network request fails
*
* @example
* ```typescript
* const user = await ds.create({
* name: 'Alice',
* email: 'alice@example.com'
* });
* ```
*/
async create(record: Partial<T>): Promise<T> {
// ...
}Inline Comments
typescript
// ✅ Good - Explain why, not what
// Use exponential backoff to avoid overwhelming the server
const delay = baseDelay * Math.pow(2, attempt);
// ❌ Bad - Obvious comment
// Set delay to base delay times 2 to the power of attempt
const delay = baseDelay * Math.pow(2, attempt);🧪 Testing Guidelines
Test Structure
typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { DataSource } from '../src/core/DataSource';
describe('DataSource', () => {
let ds: DataSource<User>;
beforeEach(() => {
ds = new DataSource<User>({
data: [
{ id: 1, name: 'Alice', email: 'alice@example.com' }
]
});
});
describe('create()', () => {
it('should create a new record', async () => {
const newUser = await ds.create({
name: 'Bob',
email: 'bob@example.com'
});
expect(newUser.id).toBeDefined();
expect(newUser.name).toBe('Bob');
expect(ds.data?.length).toBe(2);
});
it('should emit afterCreate event', async () => {
const spy = vi.fn();
ds.on('afterCreate', spy);
await ds.create({ name: 'Bob' });
expect(spy).toHaveBeenCalledTimes(1);
});
});
});Test Coverage
- Aim for 80%+ coverage
- Test happy paths and error cases
- Test edge cases
- Test async behavior
- Test event emission
Running Tests
bash
# Run all tests
pnpm test
# Run specific test file
pnpm test DataSource.test.ts
# Run tests in watch mode
pnpm test:watch
# Generate coverage report
pnpm test:coverage🔄 Pull Request Process
Before Submitting
- ✅ Code builds successfully (
pnpm build) - ✅ All tests pass (
pnpm test) - ✅ TypeScript compiles without errors (
pnpm typecheck) - ✅ New code has tests
- ✅ Documentation updated (if needed)
- ✅ CHANGELOG updated (if applicable)
PR Template
markdown
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
How was this tested?
## Checklist
- [ ] Tests pass
- [ ] TypeScript compiles
- [ ] Documentation updated
- [ ] CHANGELOG updatedCommit Messages
Use conventional commits:
bash
# Format
<type>(<scope>): <subject>
# Examples
feat(datasource): add batch delete operation
fix(container): resolve async initialization race condition
docs(api): update DataSource API documentation
test(validation): add tests for custom validators
refactor(core): improve error handlingTypes:
feat- New featurefix- Bug fixdocs- Documentationtest- Testsrefactor- Code refactoringperf- Performance improvementchore- Maintenance tasks
Review Process
- Automated checks - CI runs tests and builds
- Code review - Maintainers review your code
- Feedback - Address review comments
- Approval - PR gets approved
- Merge - Maintainer merges the PR
📚 Documentation
When to Update Docs
- Adding new features
- Changing public APIs
- Fixing bugs that affect usage
- Adding examples
Documentation Structure
docs/
├── README.md # Documentation hub
├── guides/
│ ├── getting-started.md # Getting started guide
│ └── migration-guide.md # Migration guide
├── api/
│ ├── README.md # API overview
│ └── DataSource.md # API details
└── examples.md # Examples overviewWriting Good Documentation
markdown
# ✅ Good Documentation
## Clear Title
Brief introduction explaining what this is.
### Example
```typescript
const ds = new DataSource<User>({ url: '/api/users' });
await ds.fetch();Parameters
url- API endpoint URLdata- Optional local data array
Returns
Promise resolving to fetched data.
---
## ❓ Questions?
- **Issues:** [GitHub Issues](https://github.com/mohamad-j/Bindra/issues)
- **Discussions:** [GitHub Discussions](https://github.com/mohamad-j/Bindra/discussions)
- **Email:** [your-email@example.com]
---
## 🙏 Thank You!
Thank you for contributing to Bindra! Your efforts help make this library better for everyone.
**Contributors:**
- See [Contributors](https://github.com/mohamad-j/Bindra/graphs/contributors)
---
**Happy Contributing! 🚀**