@mcabreradev/filter
Version:
A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies
100 lines (99 loc) • 3.2 kB
JavaScript
import { createMemo, createSignal, onCleanup } from 'solid-js';
import { filter } from '../../core/filter/filter';
export function useFilter(data, expression, options) {
const filtered = createMemo(() => {
const items = data();
const expr = expression();
const opts = options?.() || {};
if (!expr || items.length === 0) {
return items;
}
return filter(items, expr, opts);
});
const isFiltering = createMemo(() => {
return expression() !== null && data().length > 0;
});
return { filtered, isFiltering };
}
export function useDebouncedFilter(data, expression, options) {
const { delay = 300, filterOptions = {} } = options || {};
const [debouncedExpr, setDebouncedExpr] = createSignal(null);
const [isPending, setIsPending] = createSignal(false);
let timeoutId;
createMemo(() => {
const expr = expression();
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
setIsPending(true);
timeoutId = setTimeout(() => {
setDebouncedExpr(() => expr);
setIsPending(false);
timeoutId = undefined;
}, delay);
onCleanup(() => {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
timeoutId = undefined;
}
});
});
const filtered = createMemo(() => {
const items = data();
const expr = debouncedExpr();
if (!expr || items.length === 0) {
return items;
}
return filter(items, expr, filterOptions);
});
return { filtered, isPending };
}
export function usePaginatedFilter(data, expression, options) {
const { pageSize: initialPageSize = 10, initialPage = 1, filterOptions = {} } = options || {};
const [currentPage, setCurrentPage] = createSignal(initialPage);
const [pageSize, setPageSizeSignal] = createSignal(initialPageSize);
const filtered = createMemo(() => {
const items = data();
const expr = expression();
if (!expr || items.length === 0) {
return items;
}
return filter(items, expr, filterOptions);
});
const totalPages = createMemo(() => {
const total = filtered().length;
const size = pageSize();
return Math.ceil(total / size);
});
const paginatedResults = createMemo(() => {
const items = filtered();
const page = currentPage();
const size = pageSize();
const start = (page - 1) * size;
return items.slice(start, start + size);
});
const setPage = (page) => {
setCurrentPage(Math.max(1, Math.min(page, totalPages())));
};
const setPageSize = (size) => {
setPageSizeSignal(Math.max(1, size));
setCurrentPage(1);
};
const nextPage = () => {
setPage(currentPage() + 1);
};
const prevPage = () => {
setPage(currentPage() - 1);
};
return {
paginatedResults,
currentPage,
totalPages,
pageSize,
setPage,
setPageSize,
nextPage,
prevPage,
};
}
export { filter };