diff --git a/lib/hooks/useAI.ts b/lib/hooks/useAI.ts index 0181487..5a7a8c6 100644 --- a/lib/hooks/useAI.ts +++ b/lib/hooks/useAI.ts @@ -147,7 +147,7 @@ export interface UseAIResult { * const { isAvailable, apis, status } = useAI(); * * // Check specific APIs - * const { isAvailable, apis, preload } = useAI({ apis: ['translator', 'summarizer'] }); + * const { isAvailable, apis, preload, getApiProgress } = useAI({ apis: ['translator', 'summarizer'] }); * * // Preload models * useEffect(() => { diff --git a/lib/hooks/useDebounce.ts b/lib/hooks/useDebounce.ts index 94a21f3..14f10aa 100644 --- a/lib/hooks/useDebounce.ts +++ b/lib/hooks/useDebounce.ts @@ -3,7 +3,7 @@ import { useEffect, useState, useRef } from 'react' /** * Custom hook that debounces a value by a specified delay. * - * @template T + * @template T - The type of the value being debounced. * @param value - The value to debounce. * @param delay - The delay in milliseconds to debounce the value. * @default 500 diff --git a/lib/hooks/useList.security.test.ts b/lib/hooks/useList.security.test.ts index 330b346..9e0593f 100644 --- a/lib/hooks/useList.security.test.ts +++ b/lib/hooks/useList.security.test.ts @@ -67,4 +67,20 @@ describe('useList Security', () => { expect(result.current.list[0]).toEqual({ id: 1 }) expect(result.current.list[1]).toEqual({ id: 2 }) }) + + it('should NOT allow upserting items via restricted keys (it should always add)', () => { + const initialList = [{ id: 1 }] + const { result } = renderHook(() => useList(initialList)) + + act(() => { + // Upserting with 'constructor' should NOT match the existing item + // even if they both have 'constructor'. It should always add the new item. + result.current.upsert({ id: 2 }, 'constructor') + }) + + // It should have 2 items now (it should NOT have replaced {id: 1}) + expect(result.current.list).toHaveLength(2) + expect(result.current.list[0]).toEqual({ id: 1 }) + expect(result.current.list[1]).toEqual({ id: 2 }) + }) }) diff --git a/lib/hooks/useList.tsx b/lib/hooks/useList.tsx index 3e8be83..58dfe6e 100644 --- a/lib/hooks/useList.tsx +++ b/lib/hooks/useList.tsx @@ -25,6 +25,20 @@ function getValueToCompare(item: T, key: string | undefined | null): any { * @template T The type of elements in the list array. * @param {T[]} [initialList=[]] The initial array state. * @returns {UseListReturn} An object containing the current array state and helper functions to modify it immutably. + * + * @example + * ```tsx + * const { list, addItem, removeBy, updateByIdx } = useList<{ id: number; name: string }>([]); + * + * // Add an item + * addItem({ id: 1, name: 'John Doe' }); + * + * // Remove item by a specific property + * removeBy('id', 1); + * + * // Update item at index 0 + * updateByIdx(0, (item) => ({ ...item, name: 'Jane Doe' })); + * ``` */ export function useList(initialList: T[] = []): UseListReturn { const [list, setList] = useState(initialList) diff --git a/lib/hooks/useThrottle.ts b/lib/hooks/useThrottle.ts index 53854ef..88327b7 100644 --- a/lib/hooks/useThrottle.ts +++ b/lib/hooks/useThrottle.ts @@ -4,7 +4,7 @@ import { useEffect, useRef, useState } from 'react' * Custom hook that throttles a value by a specified limit. * Ensuring the value updates at most once every specified limit. * - * @template T + * @template T - The type of the value being throttled. * @param value - The value to throttle. * @param limit - The limit in milliseconds to throttle the value. * @default 500