Skip to content
Open
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
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
- [Browser Support](#browser-support)
- [Migration from v3.x](#migration-from-v3x)
- [Changelog](#changelog)
- [v5.8.2 (Current)](#v582-current)
- [v5.9.0 (Current)](#v590-current)
- [v5.8.2](#v582)
- [v5.8.0](#v580)
- [v5.7.0](#v570)
- [v5.6.0](#v560)
Expand Down Expand Up @@ -166,6 +167,12 @@ const startsWithAl = filter(users, 'Al%');
// → [{ name: 'Alice', ... }]
```

> **`findAll` is an alias for `filter`** — use whichever name feels more natural:
> ```typescript
> import { findAll } from '@mcabreradev/filter';
> const result = findAll(users, { active: true }); // identical to filter()
> ```

**🎮 [Try it in the Playground →](https://mcabreradev-filter.vercel.app/playground/)**

---
Expand Down Expand Up @@ -728,7 +735,11 @@ filter(data, expression, { enableCache: true, limit: 50 });

## Changelog

### v5.8.2 (Current)
### v5.9.0 (Current)

- ✨ **New**: `findAll` — a zero-breaking-change alias for `filter` with identical signature and behavior. `import { findAll } from '@mcabreradev/filter'` returns `T[]` just like `filter`. The existing `find` lazy-iterator helper is unchanged.

### v5.8.2

- 🐛 **Bug Fix**: Wildcard regex now correctly escapes all special characters (`.`, `+`, `*`, `?`, `(`, `[`, `^`, etc.) — patterns like `%.txt` or `a.b%` no longer silently break
- 🐛 **Bug Fix**: `$timeOfDay` with `start > end` (e.g. `{ start: 22, end: 5 }`) now correctly fails validation instead of silently never matching
Expand Down
24 changes: 23 additions & 1 deletion __test__/filter.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import filter from '../src/index';
import filter, { findAll } from '../src/index';

import data from './data.json';

Expand Down Expand Up @@ -300,3 +300,25 @@ describe('Array values with OR logic (syntactic sugar for $in)', () => {
expect(result.map((u) => u.city).sort()).toEqual(['Berlin', 'Berlin', 'London']);
});
});

describe('findAll alias', () => {
it('returns same results as filter', () => {
expect(findAll(data, 'Berlin')).toEqual(filter(data, 'Berlin'));
});

it('works with object expression', () => {
const city = 'Berlin';
expect(findAll(data, { city })).toEqual(filter(data, { city }));
});

it('works with predicate function', () => {
const pred = (item: (typeof data)[0]) => item.city === 'Berlin';
expect(findAll(data, pred)).toEqual(filter(data, pred));
});

it('works with options', () => {
expect(findAll(data, 'berlin', { caseSensitive: false })).toEqual(
filter(data, 'berlin', { caseSensitive: false }),
);
});
});
8 changes: 7 additions & 1 deletion __test__/test-d/filter.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expectType, expectError } from 'tsd';
import { filter } from '../../src/core/filter';
import { filter, findAll } from '../../src/core/filter';
import type { FilterOptions } from '../../src/types';
Comment on lines 1 to 3

interface User {
Expand Down Expand Up @@ -114,3 +114,9 @@ const mixedArray: (string | number)[] = ['a', 1, 'b', 2];
expectType<(string | number)[]>(filter(mixedArray, 'a'));

expectType<(string | number)[]>(filter(mixedArray, (item) => typeof item === 'string'));

expectType<User[]>(findAll(users, 'John'));
expectType<User[]>(findAll(users, { name: 'John' }));
expectType<User[]>(findAll(users, (user) => user.age > 18));
expectType<User[]>(findAll(users, { name: 'John' }, options));
expectError(findAll('not-an-array', 'test'));
30 changes: 30 additions & 0 deletions docs/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,36 @@ const users = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];
const result = filter(users, { age: { $gte: 25 } });
```

### findAll

Alias for `filter` — identical signature and behavior. Use whichever name fits your style.

```typescript
function findAll<T>(
array: T[],
expression: Expression<T>,
options?: FilterOptions
): T[]
```

**Example:**
```typescript
import { findAll } from '@mcabreradev/filter';

const users = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];

// Exactly the same as calling filter()
const result = findAll(users, { age: { $gte: 25 } });
```

::: tip
`findAll` and `filter` are the same function. Pick whichever reads most naturally in your codebase.
:::

::: info Looking for `find`?
The `find` export is the **lazy-iterator helper** — it finds the **first** matching item in an iterable and returns `T | undefined`. See [`filterFirst`](#filterfirst) for an eager equivalent, or use the built-in `Array.prototype.find` for simple cases.
:::

### filterLazy

Returns a lazy iterator for on-demand filtering.
Expand Down
11 changes: 9 additions & 2 deletions docs/guide/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@ Choose between two import styles:

```typescript
// Classic import (all features)
import { filter, useFilter } from '@mcabreradev/filter';
import { filter, findAll, useFilter } from '@mcabreradev/filter';

// Modular import (smaller bundle, recommended for production)
import { filter } from '@mcabreradev/filter/core';
import { filter, findAll } from '@mcabreradev/filter/core';
import { useFilter } from '@mcabreradev/filter/react';
```

::: tip `findAll` is an alias for `filter`
Both functions are identical — same signature, same results. Use whichever reads more naturally in your codebase.
```typescript
findAll(users, { active: true }); // same as filter(users, { active: true })
```
:::

::: tip Bundle Size
Modular imports reduce bundle size by **50-70%**! See [Modular Imports](/guide/modular-imports) for details.
:::
Expand Down
9 changes: 9 additions & 0 deletions docs/project/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to @mcabreradev/filter are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.9.0] - 2026-03-18

### Added
- **`findAll`**: Zero-breaking-change alias for `filter` — identical signature and behavior. The existing `find` lazy-iterator helper (returns `T | undefined`) is untouched.
```typescript
import { findAll } from ‘@mcabreradev/filter’;
const result = findAll(users, { active: true }); // identical to filter() — returns T[]
```

## [5.8.2] - 2025-11-17

### Documentation
Expand Down
2 changes: 2 additions & 0 deletions src/core/filter/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export function filter<T>(array: T[], expression: Expression<T>, options?: Filte
}
}

export const findAll = filter;

Comment on lines +105 to +106
export function clearFilterCache(): void {
globalFilterCache.clear();
memoization.clearAll();
Expand Down
2 changes: 1 addition & 1 deletion src/core/filter/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { filter, clearFilterCache, getFilterCacheStats } from './filter.js';
export { filter, findAll, clearFilterCache, getFilterCacheStats } from './filter.js';
2 changes: 1 addition & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { filter, clearFilterCache, getFilterCacheStats } from './filter/filter.js';
export { filter, findAll, clearFilterCache, getFilterCacheStats } from './filter/filter.js';
export {
filterLazy,
filterLazyAsync,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { filter } from './core/index.js';

export { filter };
export { findAll } from './core/index.js';

export { clearFilterCache, getFilterCacheStats } from './core/index.js';

Expand Down
Loading