Skip to content

Commit b6ec5ea

Browse files
Improve docs (#37)
* Improve documentation * Document more breaking changes * Serve docs with mkdocs * Update CONTRIBUTING.md
1 parent d6871b4 commit b6ec5ea

20 files changed

Lines changed: 2129 additions & 495 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ coverage
99
*.d.ts.map
1010
.tscache/
1111

12+
# MkDocs
13+
site/

BREAKING_CHANGES.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,58 @@ Attempting to access these properties in variable names or member expressions wi
8989
parser.evaluate('x.__proto__', { x: {} });
9090
parser.evaluate('__proto__', { __proto__: {} });
9191
```
92+
93+
## Version 4.0.0
94+
95+
### Concatenation Operator Changed from `||` to `|`
96+
97+
**What Changed**: The `||` operator was repurposed for logical OR (JavaScript-style). A new `|` (pipe) operator was introduced for array and string concatenation. Additionally, the `&&` operator was added for logical AND.
98+
99+
**Before (original expr-eval 2.x)**:
100+
```typescript
101+
// || was used for concatenation
102+
parser.evaluate('"hello" || " world"'); // "hello world"
103+
parser.evaluate('[1, 2] || [3, 4]'); // [1, 2, 3, 4]
104+
```
105+
106+
**After (v4.0.0+)**:
107+
```typescript
108+
// | is now used for concatenation
109+
parser.evaluate('"hello" | " world"'); // "hello world"
110+
parser.evaluate('[1, 2] | [3, 4]'); // [1, 2, 3, 4]
111+
112+
// || is now logical OR
113+
parser.evaluate('true || false'); // true
114+
parser.evaluate('false || true'); // true
115+
116+
// && is logical AND (new)
117+
parser.evaluate('true && false'); // false
118+
parser.evaluate('true && true'); // true
119+
```
120+
121+
**Migration Guide**:
122+
123+
1. **Find concatenation usage**: Search your expressions for `||` used with strings or arrays
124+
2. **Replace with pipe**: Change `||` to `|` for concatenation operations
125+
3. **Review logical operations**: If you were using `or` keyword, you can now also use `||`
126+
127+
### Package Renamed
128+
129+
The package was renamed from `expr-eval` to `@pro-fa/expr-eval` and ported to TypeScript.
130+
131+
```bash
132+
# Remove old package
133+
npm uninstall expr-eval
134+
135+
# Install new package
136+
npm install @pro-fa/expr-eval
137+
```
138+
139+
Update imports:
140+
```typescript
141+
// Before
142+
const { Parser } = require('expr-eval');
143+
144+
// After
145+
import { Parser } from '@pro-fa/expr-eval';
146+
```

CONTRIBUTING.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Contributing to expr-eval
2+
3+
Thank you for your interest in contributing to expr-eval! This document provides guidelines and information for contributors.
4+
5+
## Getting Started
6+
7+
### Prerequisites
8+
9+
- Node.js 18 or higher
10+
- npm 9 or higher
11+
12+
### Setup
13+
14+
```bash
15+
# Clone the repository
16+
git clone https://github.com/pro-fa/expr-eval.git
17+
cd expr-eval
18+
19+
# Install dependencies
20+
npm install
21+
22+
# Run tests to verify setup
23+
npm test
24+
```
25+
26+
## Development Workflow
27+
28+
### Running Tests
29+
30+
```bash
31+
# Run all tests
32+
npm test
33+
34+
# Run tests in watch mode
35+
npm run test:watch
36+
37+
# Run tests with coverage
38+
npm run test:coverage
39+
```
40+
41+
### Running Benchmarks
42+
43+
```bash
44+
# Run all benchmarks
45+
npm run bench
46+
47+
# Run specific benchmark categories
48+
npm run bench:parsing
49+
npm run bench:evaluation
50+
npm run bench:memory
51+
```
52+
53+
See [Performance Testing Guide](docs/performance.md) for details on interpreting benchmark results.
54+
55+
### Building
56+
57+
```bash
58+
# Build the library
59+
npm run build
60+
61+
# Build and watch for changes
62+
npm run build:watch
63+
```
64+
65+
### Linting
66+
67+
```bash
68+
# Run ESLint
69+
npm run lint
70+
71+
# Fix auto-fixable issues
72+
npm run lint:fix
73+
```
74+
75+
## Project Structure
76+
77+
```
78+
expr-eval/
79+
├── src/ # Source code
80+
│ ├── index.ts # Main entry point
81+
│ ├── config/ # Parser configuration
82+
│ ├── core/ # Core expression operations
83+
│ ├── errors/ # Error types and handling
84+
│ ├── functions/ # Built-in functions
85+
│ │ ├── array/ # Array functions
86+
│ │ ├── math/ # Math functions
87+
│ │ ├── object/ # Object functions
88+
│ │ ├── string/ # String functions
89+
│ │ └── utility/ # Utility functions
90+
│ ├── language-service/ # IDE integration (LSP)
91+
│ ├── operators/ # Operator implementations
92+
│ │ ├── binary/ # Binary operators
93+
│ │ └── unary/ # Unary operators
94+
│ ├── parsing/ # Parser and tokenizer
95+
│ ├── types/ # TypeScript type definitions
96+
│ └── validation/ # Expression validation
97+
├── test/ # Test files (mirrors src structure)
98+
├── benchmarks/ # Performance benchmarks
99+
├── docs/ # Documentation
100+
└── samples/ # Example integrations
101+
```
102+
103+
## Making Changes
104+
105+
### Code Style
106+
107+
- Use TypeScript for all new code
108+
- Follow the existing code style (enforced by ESLint)
109+
- Use meaningful variable and function names
110+
- Add JSDoc/TSDoc comments for public APIs
111+
112+
### Adding a New Function
113+
114+
1. **Create the function** in the appropriate directory under `src/functions/`
115+
2. **Export it** from the directory's `index.ts`
116+
3. **Register it** in `src/functions/index.ts`
117+
4. **Add tests** in the corresponding `test/functions/` directory
118+
5. **Document it** in `docs/syntax.md` under the appropriate section
119+
6. **Update quick-reference.md** if it's a commonly-used function
120+
121+
Example structure for a new string function:
122+
123+
```typescript
124+
// src/functions/string/my-function.ts
125+
import { Value } from '../../types';
126+
127+
/**
128+
* Description of what the function does.
129+
* @param str - The input string
130+
* @returns The transformed string
131+
*/
132+
export function myFunction(str: Value): string | undefined {
133+
if (typeof str !== 'string') return undefined;
134+
// Implementation
135+
return str.toUpperCase();
136+
}
137+
```
138+
139+
### Adding a New Operator
140+
141+
1. Create the operator in `src/operators/binary/` or `src/operators/unary/`
142+
2. Register it in the parser configuration
143+
3. Add tests
144+
4. Document in `docs/syntax.md`
145+
146+
### Modifying the Parser
147+
148+
Changes to the parser (`src/parsing/`) require extra care:
149+
150+
1. Ensure backward compatibility
151+
2. Add comprehensive tests for edge cases
152+
3. Run benchmarks to check performance impact
153+
4. Update documentation if syntax changes
154+
155+
## Testing Guidelines
156+
157+
### Writing Tests
158+
159+
- Use descriptive test names that explain what's being tested
160+
- Test both success cases and error cases
161+
- Test edge cases (empty arrays, undefined values, etc.)
162+
- Group related tests using `describe` blocks
163+
164+
```typescript
165+
describe('myFunction', () => {
166+
it('should transform a simple string', () => {
167+
expect(Parser.evaluate('myFunction("hello")')).toBe('HELLO');
168+
});
169+
170+
it('should return undefined for non-string input', () => {
171+
expect(Parser.evaluate('myFunction(123)')).toBeUndefined();
172+
});
173+
174+
it('should handle empty strings', () => {
175+
expect(Parser.evaluate('myFunction("")')).toBe('');
176+
});
177+
});
178+
```
179+
180+
### Test Coverage
181+
182+
Aim for high test coverage, especially for:
183+
- All public API functions
184+
- Error handling paths
185+
- Edge cases and boundary conditions
186+
187+
## Documentation
188+
189+
### Updating Documentation
190+
191+
When making changes, update the relevant documentation:
192+
193+
| Change Type | Documents to Update |
194+
|-------------|---------------------|
195+
| New function | `docs/syntax.md`, `docs/quick-reference.md` |
196+
| New operator | `docs/syntax.md`, `docs/quick-reference.md` |
197+
| Parser options | `docs/parser.md` |
198+
| Expression methods | `docs/expression.md` |
199+
| Language service | `docs/language-service.md` |
200+
| Breaking changes | `BREAKING_CHANGES.md` |
201+
202+
### Documentation Audiences
203+
204+
Remember that documentation serves different audiences:
205+
206+
- **Expression writers**: Non-programmers writing expressions (focus on `syntax.md`, `quick-reference.md`)
207+
- **Developers**: Programmers integrating the library (focus on `parser.md`, `expression.md`)
208+
- **Contributors**: People working on the library itself (focus on `performance.md`, this file)
209+
210+
## Pull Request Process
211+
212+
1. **Fork** the repository and create a feature branch
213+
2. **Make your changes** following the guidelines above
214+
3. **Add tests** for any new functionality
215+
4. **Run the test suite** and ensure all tests pass
216+
5. **Run benchmarks** if your change might affect performance
217+
6. **Update documentation** as needed
218+
7. **Submit a pull request** with a clear description of changes
219+
220+
### PR Checklist
221+
222+
- [ ] Tests pass (`npm test`)
223+
- [ ] Linting passes (`npm run lint`)
224+
- [ ] Documentation updated (if applicable)
225+
- [ ] BREAKING_CHANGES.md updated (if applicable)
226+
- [ ] Benchmarks run (if performance-sensitive)
227+
228+
## Reporting Issues
229+
230+
When reporting issues, please include:
231+
232+
- A clear description of the problem
233+
- Steps to reproduce
234+
- Expected vs actual behavior
235+
- Version of expr-eval
236+
- Node.js version
237+
- Minimal code example demonstrating the issue
238+
239+
## Security
240+
241+
If you discover a security vulnerability, please do NOT open a public issue. Instead, report it privately following the security policy in the repository.
242+
243+
## License
244+
245+
By contributing, you agree that your contributions will be licensed under the same license as the project (see [LICENSE.txt](LICENSE.txt)).
246+
247+
## Questions?
248+
249+
If you have questions about contributing, feel free to open a discussion or issue on GitHub.

0 commit comments

Comments
 (0)