Skip to content

Contributing to Bindra

Thank you for your interest in contributing to Bindra! We welcome contributions from the community.


📋 Table of Contents


📜 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.json

Available 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 issues

Editor Setup

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:

  1. Bug Fixes - Fix issues or bugs
  2. Features - Add new functionality
  3. Documentation - Improve or add docs
  4. Examples - Create usage examples
  5. Tests - Add or improve tests
  6. Performance - Optimize existing code
  7. Refactoring - Improve code quality

Finding Something to Work On

  1. Check Issues - Look for issues labeled good first issue or help wanted
  2. Browse Discussions - See what features are being discussed
  3. Fix Bugs - Found a bug? Fix it and submit a PR
  4. Improve Docs - Documentation can always be better

Before You Start

  1. Check existing issues - Avoid duplicate work
  2. Open an issue - Discuss your idea before major changes
  3. Get feedback - Ask questions in discussions
  4. 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 updated

Commit 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 handling

Types:

  • feat - New feature
  • fix - Bug fix
  • docs - Documentation
  • test - Tests
  • refactor - Code refactoring
  • perf - Performance improvement
  • chore - Maintenance tasks

Review Process

  1. Automated checks - CI runs tests and builds
  2. Code review - Maintainers review your code
  3. Feedback - Address review comments
  4. Approval - PR gets approved
  5. 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 overview

Writing 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 URL
  • data - 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! 🚀**

Released under the MIT License.