Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 151 additions & 42 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,113 @@
# AGENTS.md

## Project Overview
Rules and principles for agents working on **this** project.

`tiny-lru` is a high-performance, lightweight LRU (Least Recently Used) cache library for JavaScript with O(1) operations and optional TTL support.
---

## Setup Commands
## 1. Core Rules

```bash
npm install # Install dependencies
npm run build # Lint and build (runs lint then rollup)
npm run rollup # Build with rollup
npm run test # Run lint and tests
npm run coverage # Run tests with coverage reporting
npm run fix # Fix linting and formatting issues
npm run lint # Lint code with oxlint
```
### 1.0 Document Conventions

## Development Workflow
When updating this document, append new information or sections. Do NOT delete or overwrite existing content unless explicitly directed. Always ask before making structural changes. When in doubt, keep it.

Source code is in `src/`.
### 1.1 Forbidden Patterns

The following are **strictly prohibited**:

- Hardcoded secrets, API keys, or credentials.
- `eval()`, `exec()` at any level.
- Star imports (`import * as foo from 'bar'`).
- Mutating a list while iterating over it.
- `new Array()` — use `Array()` or `Array.from()` instead (oxlint will warn).

### 1.2 Security Rules

Follow the [OWASP Top 10](https://owasp.org/www-project-top-10/) for every piece of code written:

- **lint**: Check and fix linting issues with oxlint
- **fix**: Fix linting and formatting issues
- **build**: Lint + rollup build
- **coverage**: Run test suite with coverage reporting
- Avoid unsafe operations, validate inputs, prevent injection risks.

## Project Structure
### 1.3 Git Operations

- **Never rebase under any circumstance without explicit agreement from the user.** Never assume your decision is correct.
- Never force push.

### 1.4 Core Principles

- **DRY (Don't Repeat Yourself)**: Extract common logic into reusable functions; avoid duplication.
- **YAGNI (You Ain't Gonna Need It)**: Implement only what's needed; avoid over-engineering.
- **SOLID**: Follow single responsibility, open/closed, and interface segregation principles.

---

## 2. Project Context

### 2.0 Expected Project Layout

`tiny-lru` is a high-performance, lightweight LRU (Least Recently Used) cache library for JavaScript with O(1) operations and optional TTL support.

```
├── src/lru.js # Main LRU cache implementation
├── tests/ # Test files
├── benchmarks/ # Performance benchmarks
├── benchmarks/ # Performance benchmarks
├── dist/ # Built distribution files
│ ├── tiny-lru.js # ES Modules
│ ├── tiny-lru.cjs # CommonJS
│ └── tiny-lru.min.js # Minified ESM
├── types/ # TypeScript definitions
├── docs/ # Documentation
├── rollup.config.js # Build configuration
└── package.json # Project configuration
└── package.json # Project configuration
```

## Code Style
### 2.1 Quick Commands

| Command | Purpose |
|-------------------|---------------------------------------------------|
| `npm install` | Install dependencies |
| `npm run build` | Lint and build (runs lint then rollup) |
| `npm run rollup` | Build with rollup |
| `npm run test` | Run lint and tests |
| `npm run coverage`| Run tests with coverage reporting |
| `npm run fix` | Fix linting and formatting issues |
| `npm run lint` | Lint code with oxlint |

---

## 3. Code Conventions

### 3.1 Language & Tooling

- **JavaScript/TypeScript**: CommonJS, ESM, and minified ESM outputs via Rollup
- **Package manager**: `npm`
- **Linting**: `oxlint`
- **Formatting**: (via `npm run fix`)
- **Testing**: Node.js built-in test runner (`node --test`)

### 3.2 Style

- Indentation: Tabs
- Quotes: Double quotes
- Semicolons: Required
- Array constructor: Avoid `new Array()` (oxlint will warn)

## Development Principles
### 3.3 Error Handling

Not applicable — internal LRU operations should not surface errors; handle gracefully.

### 3.4 Testing

- Framework: Node.js built-in test runner (`node --test`)
- Tests: 149 tests across 26 suites
- Coverage: 100% lines, 99.28% branches, 100% functions
- Test pattern: `tests/**/*.js`
- All tests must pass with 100% line coverage before merging
- Run: `npm test` (lint + tests) or `npm run coverage` for coverage report

---

- **DRY (Don't Repeat Yourself)**: Extract common logic into reusable functions; avoid duplication
- **YAGNI (You Ain't Gonna Need It)**: Implement only what's needed; avoid over-engineering
- **SOLID**: Follow single responsibility, open/closed, and interface segregation principles
- **OWASP**: Prioritize security; avoid unsafe operations, validate inputs, prevent injection risks
## 4. API Conventions

## API Reference
### 4.1 API Reference

- `lru(max, ttl, resetTtl)` - Factory function to create cache
- `LRU` class - Direct instantiation with `new LRU(max, ttl, resetTtl)`
Expand All @@ -65,26 +117,83 @@ Source code is in `src/`.
- Properties: `first`, `last`, `max`, `size`, `ttl`, `resetTtl`
- `peek(key)` - Retrieve value without moving it (no LRU update, no TTL check)

## Testing
---

- Framework: Node.js built-in test runner (`node --test`)
- Tests: 149 tests across 26 suites
- Coverage: 100% lines, 99.28% branches, 100% functions
- Test pattern: `tests/**/*.js`
- All tests must pass with 100% line coverage before merging
- Run: `npm test` (lint + tests) or `npm run coverage` for coverage report
## 5. Git Conventions

### 5.1 Commit Messages

Follow [Conventional Commits](https://www.conventionalcommits.org/):

```
feat: add TTL support to LRU cache
fix: correct LRU eviction order for edge case
docs: update AGENTS.md with new conventions
test: add coverage for keysByTTL method
chore: update rollup configuration
```

### 5.2 Branching

- Main branch is `main`.
- Feature branches: `feat/<short-desc>` or `fix/<short-desc>`.
- Never commit directly to `main`. Always create a feature branch first, then open a PR targeting `main`.

### 5.3 Code Review

- All changes require tests to pass and maintain coverage requirements.
- 100% line coverage is required before merging.

---

## Common Issues to Avoid
## 6. Operational Rules

- **Memory leaks**: When removing items from the linked list, always clear `prev`/`next` pointers to allow garbage collection
- **LRU order pollution**: Methods like `entries()` and `values()` should access items directly rather than calling `get()`, which moves items and can delete expired items mid-iteration
- **TTL edge cases**: Direct property access (`this.items[key]`) should be used instead of `has()` when you need to inspect expired-but-not-yet-deleted items
- **Dead code**: Always verify edge case code is actually reachable before adding special handling
- **Constructor assignment**: Use `let` not `const` for variables that may be reassigned (e.g., in `setWithEvicted`)
### 6.1 Coverage

## Implementation Notes
Tests must maintain **100% line coverage**. Every new function or class needs test coverage. No exceptions.

```bash
npm run coverage
```

### 6.2 Common Issues to Avoid

- **Memory leaks**: When removing items from the linked list, always clear `prev`/`next` pointers to allow garbage collection.
- **LRU order pollution**: Methods like `entries()` and `values()` should access items directly rather than calling `get()`, which moves items and can delete expired items mid-iteration.
- **TTL edge cases**: Direct property access (`this.items[key]`) should be used instead of `has()` when you need to inspect expired-but-not-yet-deleted items.
- **Dead code**: Always verify edge case code is actually reachable before adding special handling.
- **Constructor assignment**: Use `let` not `const` for variables that may be reassigned (e.g., in `setWithEvicted`).

### 6.3 Development Workflow

Source code is in `src/`.

- **install**: `npm install` — Install dependencies
- **lint**: `npm run lint` — Check and fix linting issues with oxlint
- **fix**: `npm run fix` — Fix linting and formatting issues
- **build**: `npm run build` — Lint + rollup build
- **rollup**: `npm run rollup` — Build with rollup
- **test**: `npm run test` — Run lint and tests
- **coverage**: `npm run coverage` — Run test suite with coverage reporting

---

## 7. Session Learnings

### 7.1 Implementation Notes

- The LRU uses a doubly-linked list with `first` and `last` pointers for O(1) operations
- TTL is stored per-item as an `expiry` timestamp; `0` means no expiration
- `moveToEnd()` is the core method for maintaining LRU order - item is always moved to the `last` position
- `setWithEvicted()` optimizes updates by avoiding the full `set()` path for existing keys

---

## 8. Checklist Before Marking a TODO Complete

- [ ] All code follows style conventions (tabs, double quotes, semicolons).
- [ ] No forbidden patterns used (`new Array()`, etc.).
Comment thread
avoidwork marked this conversation as resolved.
- [ ] Unit tests written and passing.
- [ ] 100% line coverage maintained (`npm run coverage`).
- [ ] `npm run lint` passes with no errors.
- [ ] No hardcoded secrets or credentials introduced.
50 changes: 37 additions & 13 deletions docs/CODE_STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

Coding conventions for tiny-lru source code.

---

## Editor Configuration

Set your editor to use **tabs** for indentation.

## Forbidden Patterns

The following are **strictly prohibited**:

- Hardcoded secrets, API keys, or credentials.
- `eval()`, `exec()`, `__import__()` at any level.
- `*` imports (`from x import *`).
- Mutating a list while iterating over it.
- `new Array()` — use `Array()` or `Array.from()` instead (oxlint will warn).

## JavaScript Style

### Formatting
Expand Down Expand Up @@ -53,6 +65,9 @@ this.items = Object.create(null);

// Use Array.from() for pre-allocated arrays
const result = Array.from({ length: this.size });

// Never use new Array() - use Array() or Array.from() instead
const items = Array(10); // NOT new Array(10)
```

## JSDoc Comments
Expand Down Expand Up @@ -101,9 +116,6 @@ setWithEvicted() { }
// Variables: camelCase
const maxSize = 1000;
let currentItem = null;

// Constants: camelCase (not UPPER_SNAKE)
const defaultMax = 1000;
```

## Method Patterns
Expand Down Expand Up @@ -177,20 +189,32 @@ export class LRU {

## Error Handling

Use TypeError with clear messages:
Not applicable — internal LRU operations should not surface errors; handle gracefully.

```javascript
if (isNaN(max) || max < 0) {
throw new TypeError("Invalid max value");
}
## Testing and Coverage

- Framework: Node.js built-in test runner (`node --test`)
- Tests: 149 tests across 26 suites
- Coverage: 100% lines, 99.28% branches, 100% functions
- Test pattern: `tests/**/*.js`
- All tests must pass with 100% line coverage before merging
- Run: `npm test` (lint + tests) or `npm run coverage` for coverage report

### Coverage

Tests must maintain **100% line coverage**. Every new function or class needs test coverage. No exceptions.

```bash
npm run coverage
```

## Testing and Coverage
## Common Issues to Avoid

- All tests must pass before merging
- 100% line coverage required
- Run tests with `npm test` (includes linting)
- Generate coverage report with `npm run coverage`
- **Memory leaks**: When removing items from the linked list, always clear `prev`/`next` pointers to allow garbage collection.
- **LRU order pollution**: Methods like `entries()` and `values()` should access items directly rather than calling `get()`, which moves items and can delete expired items mid-iteration.
- **TTL edge cases**: Direct property access (`this.items[key]`) should be used instead of `has()` when you need to inspect expired-but-not-yet-deleted items.
- **Dead code**: Always verify edge case code is actually reachable before adding special handling.
- **Constructor assignment**: Use `let` not `const` for variables that may be reassigned (e.g., in `setWithEvicted`).

## Lint Configuration

Expand Down
Loading