diff --git a/README.md b/README.md index b7ac547..139c2e0 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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/)** --- @@ -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 diff --git a/__test__/filter.test.ts b/__test__/filter.test.ts index f7b3293..556b236 100644 --- a/__test__/filter.test.ts +++ b/__test__/filter.test.ts @@ -1,4 +1,4 @@ -import filter from '../src/index'; +import filter, { findAll } from '../src/index'; import data from './data.json'; @@ -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 }), + ); + }); +}); diff --git a/__test__/test-d/filter.test-d.ts b/__test__/test-d/filter.test-d.ts index 81d1ce9..a2ff4b4 100644 --- a/__test__/test-d/filter.test-d.ts +++ b/__test__/test-d/filter.test-d.ts @@ -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'; interface User { @@ -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(findAll(users, 'John')); +expectType(findAll(users, { name: 'John' })); +expectType(findAll(users, (user) => user.age > 18)); +expectType(findAll(users, { name: 'John' }, options)); +expectError(findAll('not-an-array', 'test')); diff --git a/docs/api/reference.md b/docs/api/reference.md index 2de049b..6b0ae30 100644 --- a/docs/api/reference.md +++ b/docs/api/reference.md @@ -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( + array: T[], + expression: Expression, + 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. diff --git a/docs/guide/quick-start.md b/docs/guide/quick-start.md index a78f540..da727f5 100644 --- a/docs/guide/quick-start.md +++ b/docs/guide/quick-start.md @@ -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. ::: diff --git a/docs/project/changelog.md b/docs/project/changelog.md index 2368bc1..687410e 100644 --- a/docs/project/changelog.md +++ b/docs/project/changelog.md @@ -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 diff --git a/src/core/filter/filter.ts b/src/core/filter/filter.ts index 70b3485..f23670e 100644 --- a/src/core/filter/filter.ts +++ b/src/core/filter/filter.ts @@ -102,6 +102,8 @@ export function filter(array: T[], expression: Expression, options?: Filte } } +export const findAll = filter; + export function clearFilterCache(): void { globalFilterCache.clear(); memoization.clearAll(); diff --git a/src/core/filter/index.ts b/src/core/filter/index.ts index c3354b8..88177c8 100644 --- a/src/core/filter/index.ts +++ b/src/core/filter/index.ts @@ -1 +1 @@ -export { filter, clearFilterCache, getFilterCacheStats } from './filter.js'; +export { filter, findAll, clearFilterCache, getFilterCacheStats } from './filter.js'; diff --git a/src/core/index.ts b/src/core/index.ts index ae95aad..ec8ca66 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,4 +1,4 @@ -export { filter, clearFilterCache, getFilterCacheStats } from './filter/filter.js'; +export { filter, findAll, clearFilterCache, getFilterCacheStats } from './filter/filter.js'; export { filterLazy, filterLazyAsync, diff --git a/src/index.ts b/src/index.ts index 0167025..c07330e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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';