Contributing to Filter
Thank you for your interest in contributing to @mcabreradev/filter! This guide will help you get started.
Table of Contents
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Development Workflow
- Testing
- Documentation
- Pull Request Process
- Coding Standards
- Framework Integrations
- Performance Considerations
Code of Conduct
By participating in this project, you agree to maintain a respectful and inclusive environment for all contributors.
Our Standards
- Use welcoming and inclusive language
- Be respectful of differing viewpoints and experiences
- Gracefully accept constructive criticism
- Focus on what is best for the community
- Show empathy towards other community members
Getting Started
Fork and Clone
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/filter.git
cd filter- Add upstream remote:
git remote add upstream https://github.com/mcabreradev/filter.gitStay Synced
Keep your fork up to date:
git fetch upstream
git checkout main
git merge upstream/mainDevelopment Setup
Prerequisites
- Node.js 18+ or 20+
- pnpm 8+ (recommended)
Installation
pnpm installAvailable Scripts
pnpm test
pnpm test:watch
pnpm test:coverage
pnpm test:types
pnpm build
pnpm type-check
pnpm docs:dev
pnpm docs:buildProject Structure
filter/
├── src/
│ ├── core/ # Core filter functionality
│ │ ├── filter.ts
│ │ ├── filter-lazy.ts
│ │ └── index.ts
│ ├── operators/ # Operator implementations
│ │ ├── comparison.operators.ts
│ │ ├── logical.operators.ts
│ │ ├── string.operators.ts
│ │ ├── array.operators.ts
│ │ └── operator-processor.ts
│ ├── comparison/ # Comparison utilities
│ │ ├── deep-compare.ts
│ │ ├── object-compare.ts
│ │ └── property-compare.ts
│ ├── config/ # Configuration
│ │ ├── config-builder.ts
│ │ └── default-config.ts
│ ├── integrations/ # Framework integrations
│ │ ├── react/
│ │ ├── vue/
│ │ ├── svelte/
│ │ └── shared/
│ ├── predicate/ # Predicate functions
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ └── validation/ # Validation schemas
├── __test__/ # Test files
├── docs/ # Documentation
├── examples/ # Usage examples
└── build/ # Build outputDevelopment Workflow
1. Create a Branch
git checkout -b feature/your-feature-nameBranch naming conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions/changeschore/- Maintenance tasks
2. Make Changes
- Write clean, readable code
- Follow TypeScript best practices
- Add/update tests
- Update documentation
3. Test Your Changes
pnpm test
pnpm test:coverage
pnpm type-check4. Commit Changes
Follow Conventional Commits:
git commit -m "feat: add new operator for date filtering"
git commit -m "fix: resolve memory leak in memoization"
git commit -m "docs: update React integration guide"Commit types:
feat:- New featurefix:- Bug fixdocs:- Documentation changesstyle:- Code style changes (formatting)refactor:- Code refactoringtest:- Test changeschore:- Maintenance tasksperf:- Performance improvements
5. Push and Create PR
git push origin feature/your-feature-nameOpen a Pull Request on GitHub.
Testing
Unit Tests
All new features and bug fixes must include tests.
pnpm test
pnpm test:watch
pnpm test filter.test.tsType Tests
Type-level tests ensure TypeScript types work correctly:
pnpm test:typesCoverage
Maintain 100% code coverage:
pnpm test:coverageWriting Tests
Follow these guidelines:
1. Descriptive Names
it('should filter users by age greater than 18', () => {
// test
});2. Arrange-Act-Assert Pattern
it('should filter array by simple condition', () => {
const data = [{ age: 25 }, { age: 30 }];
const expression = { age: { $gt: 26 } };
const result = filter(data, expression);
expect(result).toEqual([{ age: 30 }]);
});3. Test Edge Cases
it('should handle empty arrays', () => {
expect(filter([], expression)).toEqual([]);
});
it('should handle null values', () => {
const data = [{ age: null }, { age: 25 }];
expect(filter(data, { age: { $gt: 20 } })).toEqual([{ age: 25 }]);
});4. Test Error Conditions
it('should throw error for invalid operator', () => {
expect(() => filter(data, { age: { $invalid: 20 } }))
.toThrow('Invalid operator');
});Documentation
Code Documentation
Add JSDoc comments for public APIs:
/**
* Filters an array based on the provided expression.
*
* @template T - The type of items in the array
* @param data - The array to filter
* @param expression - The filter expression
* @param options - Optional configuration
* @returns Filtered array
*
* @example
* ```typescript
* const users = [{ age: 25 }, { age: 30 }];
* const filtered = filter(users, { age: { $gte: 26 } });
* ```
*/
export function filter<T>(
data: T[],
expression: Expression<T>,
options?: FilterOptions
): T[] {
// implementation
}Documentation Site
Documentation is built with VitePress:
pnpm docs:dev
pnpm docs:buildWhen adding features:
- Update relevant documentation pages
- Add examples to
docs/examples/ - Update API reference
- Add to changelog
Pull Request Process
Before Submitting
Checklist:
- [ ] Tests pass locally
- [ ] Code follows style guidelines
- [ ] Documentation is updated
- [ ] Type checks pass
- [ ] No linter errors
- [ ] Commit messages follow conventions
- [ ] Branch is up to date with main
PR Description Template
## Description
Brief description of changes and motivation.
## Type of Change
- [ ] ✨ New feature
- [ ] 🛠️ Bug fix
- [ ] ❌ Breaking change
- [ ] 🧹 Code refactor
- [ ] 📝 Documentation
- [ ] 🗑️ Chore
## Testing
- [ ] Unit tests added/updated
- [ ] Type tests added/updated
- [ ] All tests pass
- [ ] Coverage maintained at 100%
## Documentation
- [ ] Documentation updated
- [ ] Examples added/updated
- [ ] API reference updated
- [ ] Changelog updated
## Checklist
- [ ] Code builds successfully
- [ ] No TypeScript errors
- [ ] No linter issues
- [ ] Follows coding standardsReview Process
- Maintainers review your PR
- Address feedback and requested changes
- Once approved, PR will be merged
- Your contribution will be included in the next release
Coding Standards
TypeScript
- Use strict TypeScript mode
- Prefer
interfaceovertypefor objects - Avoid
any- use proper types - Use type guards for runtime checks
- Leverage type inference
interface User {
id: number;
name: string;
age: number;
}
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'name' in value &&
'age' in value
);
}Code Style
- Use functional programming patterns
- Follow DRY principle
- Keep functions small and focused
- Use meaningful names
- Avoid side effects
const filterByAge = (minAge: number) => (user: User) => user.age >= minAge;
const adults = users.filter(filterByAge(18));Naming Conventions
camelCase- variables, functions, methodsPascalCase- types, interfaces, classeskebab-case- file namesUPPERCASE- constants, environment variables
const userName = 'John';
interface UserProfile {
id: number;
}
const MAX_RETRIES = 3;File Organization
feature/
├── feature.ts # Main implementation
├── feature.types.ts # Type definitions
├── feature.utils.ts # Utility functions
├── feature.constants.ts # Constants
├── feature.test.ts # Unit tests
└── index.ts # Public exportsFramework Integrations
When adding framework integrations:
1. Follow Framework Best Practices
React: Use hooks, avoid class components Vue: Use Composition API Svelte: Use stores
2. Maintain Type Safety
export function useFilter<T>(
data: T[],
expression: Expression<T>,
options?: FilterOptions
): UseFilterResult<T> {
// implementation
}3. Add Comprehensive Examples
Include examples for common use cases.
4. Update Framework Documentation
Add/update documentation in docs/frameworks/.
5. Add Integration Tests
Test framework-specific behavior.
Performance Considerations
Benchmarking
Benchmark performance-critical changes:
console.time('filter');
const result = filter(largeDataset, expression);
console.timeEnd('filter');Optimization Guidelines
- Use memoization for expensive operations
- Implement lazy evaluation where appropriate
- Avoid unnecessary re-renders in React
- Minimize reactivity overhead in Vue
- Optimize store updates in Svelte
Memory Management
- Clear caches when appropriate
- Avoid memory leaks in subscriptions
- Use weak references where possible
Questions and Support
- Questions: Open a GitHub Discussion
- Bugs: Open a GitHub Issue
- Security: Email security@mcabreradev.com
Recognition
Contributors are recognized in:
- README.md contributors section
- Release notes
- GitHub contributors page
Thank you for contributing! 🎉
License
By contributing, you agree that your contributions will be licensed under the MIT License.