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
2 changes: 1 addition & 1 deletion lib/hooks/useAI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
2 changes: 1 addition & 1 deletion lib/hooks/useDebounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions lib/hooks/useList.security.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
})
})
14 changes: 14 additions & 0 deletions lib/hooks/useList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ function getValueToCompare<T>(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<T>} 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<T>(initialList: T[] = []): UseListReturn<T> {
const [list, setList] = useState<T[]>(initialList)
Expand Down
2 changes: 1 addition & 1 deletion lib/hooks/useThrottle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading