import * as React from 'react'; export function useSet( initialValues: readonly T[] | null, ): ISet { const [set, setSet] = React.useState(() => new Set(initialValues)); return { raw: set, add: React.useCallback((value: T) => { setSet((set) => { if (set.has(value)) { return set; } const copy = new Set(set); copy.add(value); return copy; }); }, []), clear: React.useCallback(() => { setSet((set) => { return set.size === 0 ? set : new Set(); }); }, []), delete: React.useCallback( (value: T) => setSet((set) => { if (!set.has(value)) { return set; } const copy = new Set(set); copy.delete(value); return copy; }), [], ), has: React.useCallback((value: T) => set.has(value), [set]), map: React.useCallback( (callbackFn) => { const result: ReturnType[] = []; for (const value of set) { result.push(callbackFn(value, result.length, set)); } return result; }, [set], ), size: set.size, }; } interface ISet { raw: Set; add(value: T): void; clear(): void; delete(value: T): void; has(value: T): boolean; map(callbackFn: (value: T, index: number, set: Set) => U): U[]; readonly size: number; } function isFunction(value: unknown): value is (...args: any[]) => any { return typeof value === 'function'; }