react-hooks-core 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/hooks/useStorage.ts"],"names":["useState","useRef","useEffect","useCallback","storageKey"],"mappings":"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","file":"chunk-3QXSUE3X.js","sourcesContent":["import { useState, useEffect, useCallback, useRef } from 'react'\nimport type { IUseStorageOptions, IUseStorageReturn, StorageValue } from '../interface'\n\n/**\n * Shared polling manager for all useStorage hooks\n * Prevents multiple intervals when using multiple hooks\n */\nclass StoragePollingManager {\n private intervalId: NodeJS.Timeout | null = null\n private subscribers: Set<() => void> = new Set()\n private readonly POLL_INTERVAL = 2000 // 2 seconds - longer interval to reduce overhead\n\n subscribe(callback: () => void): () => void {\n this.subscribers.add(callback)\n\n // Start polling if this is the first subscriber\n if (this.subscribers.size === 1 && this.intervalId === null) {\n this.startPolling()\n }\n\n // Return unsubscribe function\n return () => {\n this.subscribers.delete(callback)\n\n // Stop polling if no more subscribers\n if (this.subscribers.size === 0 && this.intervalId !== null) {\n this.stopPolling()\n }\n }\n }\n\n private startPolling(): void {\n if (typeof window === 'undefined') {\n return\n }\n\n this.intervalId = setInterval(() => {\n // Notify all subscribers\n this.subscribers.forEach((callback) => {\n try {\n callback()\n } catch (error) {\n // Silently handle errors in callbacks\n }\n })\n }, this.POLL_INTERVAL)\n }\n\n private stopPolling(): void {\n if (this.intervalId !== null) {\n if (typeof clearInterval !== 'undefined') {\n clearInterval(this.intervalId)\n }\n this.intervalId = null\n }\n }\n}\n\n// Singleton instance\nconst pollingManager = new StoragePollingManager()\n\n/**\n * Hook for managing storage (localStorage, sessionStorage, or cookies)\n * Supports string, number, boolean, array, and JSON object values\n *\n * @template T - Type of the stored value\n * @param {string} key - Storage key\n * @param {IUseStorageOptions<T>} options - Optional configuration\n * @returns {IUseStorageReturn<T>} Storage management object\n *\n * @example\n * ```tsx\n * function App() {\n * const { value, setValue, removeValue } = useStorage('user', {\n * defaultValue: null,\n * storageType: 'localStorage'\n * })\n *\n * return (\n * <div>\n * <p>Value: {JSON.stringify(value)}</p>\n * <button onClick={() => setValue({ name: 'John' })}>Set Value</button>\n * <button onClick={removeValue}>Remove</button>\n * </div>\n * )\n * }\n * ```\n *\n * @see https://github.com/yourusername/react-hookify#usestorage\n */\nexport function useStorage<T extends StorageValue = StorageValue>(\n key: string,\n options?: IUseStorageOptions<T>\n): IUseStorageReturn<T> {\n const {\n storageType = 'localStorage',\n defaultValue = null,\n sync = false,\n cookieOptions,\n onChange,\n } = options || {}\n\n // SSR-safe initialization\n const [value, setValueState] = useState<T | null>(() => {\n if (typeof window === 'undefined') {\n return defaultValue ?? null\n }\n\n try {\n let rawValue: string | null = null\n\n if (storageType === 'cookie') {\n rawValue = getCookie(key)\n } else if (storageType === 'localStorage') {\n rawValue = window.localStorage.getItem(key)\n } else if (storageType === 'sessionStorage') {\n rawValue = window.sessionStorage.getItem(key)\n }\n\n if (rawValue === null) {\n return defaultValue ?? null\n }\n\n // Try to parse as JSON first, fallback to string\n try {\n const parsed = JSON.parse(rawValue)\n return parsed as T\n } catch {\n // If not JSON, return as string (handles plain strings stored without JSON.stringify)\n return rawValue as T\n }\n } catch (error) {\n console.warn(`Error reading storage for key \"${key}\":`, error)\n return defaultValue ?? null\n }\n })\n\n const onChangeRef = useRef(onChange)\n const keyRef = useRef(key)\n const storageTypeRef = useRef(storageType)\n const lastValueRef = useRef<string | null>(null) // Track last raw value for polling optimization\n\n // Update refs\n useEffect(() => {\n onChangeRef.current = onChange\n keyRef.current = key\n storageTypeRef.current = storageType\n }, [onChange, key, storageType])\n\n // Set value in storage\n const setValue = useCallback(\n (newValue: T | null) => {\n if (typeof window === 'undefined') {\n return\n }\n\n try {\n const storageKey = keyRef.current\n const type = storageTypeRef.current\n\n if (newValue === null) {\n // Remove value\n if (type === 'cookie') {\n removeCookie(storageKey, cookieOptions)\n lastValueRef.current = null\n } else if (type === 'localStorage') {\n window.localStorage.removeItem(storageKey)\n lastValueRef.current = null\n } else if (type === 'sessionStorage') {\n window.sessionStorage.removeItem(storageKey)\n lastValueRef.current = null\n }\n } else {\n // Store value - serialize based on type for efficiency\n // Strings are stored as-is, other types are JSON stringified\n const stringValue = typeof newValue === 'string' ? newValue : JSON.stringify(newValue)\n\n if (type === 'cookie') {\n setCookie(storageKey, stringValue, cookieOptions)\n lastValueRef.current = stringValue\n } else if (type === 'localStorage') {\n window.localStorage.setItem(storageKey, stringValue)\n lastValueRef.current = stringValue\n } else if (type === 'sessionStorage') {\n window.sessionStorage.setItem(storageKey, stringValue)\n lastValueRef.current = stringValue\n }\n }\n\n setValueState(newValue)\n onChangeRef.current?.(newValue)\n } catch (error) {\n console.warn(`Error setting ${storageTypeRef.current} for key \"${keyRef.current}\":`, error)\n }\n },\n [cookieOptions]\n )\n\n // Remove value from storage\n const removeValue = useCallback(() => {\n setValue(null)\n }, [setValue])\n\n // Clear all storage (only for localStorage/sessionStorage)\n const clear = useCallback(() => {\n if (typeof window === 'undefined') {\n return\n }\n\n try {\n const type = storageTypeRef.current\n if (type === 'localStorage') {\n window.localStorage.clear()\n } else if (type === 'sessionStorage') {\n window.sessionStorage.clear()\n }\n // Cookies cannot be cleared all at once\n } catch (error) {\n console.warn(`Error clearing ${storageTypeRef.current}:`, error)\n }\n }, [])\n\n // Check if value exists\n const hasValue = value !== null\n\n // Sync with other tabs/windows (only for localStorage)\n useEffect(() => {\n if (typeof window === 'undefined' || !sync || storageType !== 'localStorage') {\n return\n }\n\n const handleStorageChange = (e: StorageEvent) => {\n if (e.key === key && e.storageArea === window.localStorage) {\n const rawValue = e.newValue\n lastValueRef.current = rawValue\n\n let newValue: T | null = null\n if (rawValue !== null) {\n try {\n // Try to parse as JSON first\n newValue = JSON.parse(rawValue) as T\n } catch {\n // If not JSON, treat as string\n newValue = rawValue as T\n }\n }\n\n setValueState(newValue)\n onChangeRef.current?.(newValue)\n }\n }\n\n window.addEventListener('storage', handleStorageChange)\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n }\n }, [key, sync, storageType])\n\n // Listen for changes in the same window (for programmatic changes)\n // Uses shared polling manager to prevent multiple intervals when using multiple hooks\n // Polls for localStorage, sessionStorage, and cookies to detect programmatic changes\n // Only skips polling when sync is enabled for localStorage (storage events handle it)\n useEffect(() => {\n if (typeof window === 'undefined') {\n return\n }\n\n const type = storageTypeRef.current\n\n // Skip polling only if sync is enabled for localStorage (storage events handle it)\n if (sync && type === 'localStorage') {\n return\n }\n\n const checkValue = () => {\n try {\n const storageKey = keyRef.current\n const currentType = storageTypeRef.current\n let rawValue: string | null = null\n\n if (currentType === 'cookie') {\n rawValue = getCookie(storageKey)\n } else if (currentType === 'localStorage') {\n rawValue = window.localStorage.getItem(storageKey)\n } else if (currentType === 'sessionStorage') {\n rawValue = window.sessionStorage.getItem(storageKey)\n }\n\n // Only update if the raw value changed (avoid unnecessary JSON.stringify)\n if (rawValue !== lastValueRef.current) {\n lastValueRef.current = rawValue\n\n let currentValue: T | null = null\n if (rawValue !== null) {\n try {\n // Try to parse as JSON first\n currentValue = JSON.parse(rawValue) as T\n } catch {\n // If not JSON, treat as string\n currentValue = rawValue as T\n }\n }\n\n setValueState(currentValue)\n onChangeRef.current?.(currentValue)\n }\n } catch (error) {\n // Silently fail\n }\n }\n\n // Initialize last value (with error handling)\n const storageKey = keyRef.current\n try {\n if (type === 'cookie') {\n lastValueRef.current = getCookie(storageKey)\n } else if (type === 'localStorage') {\n lastValueRef.current = window.localStorage.getItem(storageKey)\n } else if (type === 'sessionStorage') {\n lastValueRef.current = window.sessionStorage.getItem(storageKey)\n }\n } catch (error) {\n // Silently handle errors during initialization\n lastValueRef.current = null\n }\n\n // Subscribe to shared polling manager (prevents multiple intervals)\n const unsubscribe = pollingManager.subscribe(checkValue)\n\n return () => {\n unsubscribe()\n lastValueRef.current = null\n }\n }, [key, storageType, sync])\n\n return {\n value,\n setValue,\n removeValue,\n hasValue,\n clear,\n }\n}\n\n/**\n * Get cookie value\n */\nfunction getCookie(name: string): string | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n const nameEQ = name + '='\n const cookies = document.cookie.split(';')\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i]\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1, cookie.length)\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(cookie.substring(nameEQ.length, cookie.length))\n }\n }\n\n return null\n}\n\n/**\n * Set cookie value\n */\nfunction setCookie(\n name: string,\n value: string,\n options?: IUseStorageOptions['cookieOptions']\n): void {\n if (typeof document === 'undefined') {\n return\n }\n\n const { expires, path = '/', domain, secure = false, sameSite = 'Lax' } = options || {}\n\n let cookieString = `${name}=${encodeURIComponent(value)}`\n\n // Handle expiration: undefined = default (365 days), 0 = session cookie, number = days\n if (expires !== undefined && expires !== 0) {\n const date = new Date()\n date.setTime(date.getTime() + expires * 24 * 60 * 60 * 1000)\n cookieString += `; expires=${date.toUTCString()}`\n } else if (expires === undefined) {\n // Default to 365 days if not specified\n const date = new Date()\n date.setTime(date.getTime() + 365 * 24 * 60 * 60 * 1000)\n cookieString += `; expires=${date.toUTCString()}`\n }\n // If expires === 0, don't add expires attribute (session cookie)\n\n cookieString += `; path=${path}`\n\n if (domain) {\n cookieString += `; domain=${domain}`\n }\n\n if (secure) {\n cookieString += '; secure'\n }\n\n cookieString += `; SameSite=${sameSite}`\n\n document.cookie = cookieString\n}\n\n/**\n * Remove cookie\n */\nfunction removeCookie(name: string, options?: IUseStorageOptions['cookieOptions']): void {\n if (typeof document === 'undefined') {\n return\n }\n\n const { path = '/', domain } = options || {}\n\n let cookieString = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`\n\n if (domain) {\n cookieString += `; domain=${domain}`\n }\n\n document.cookie = cookieString\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -1 +1,2 @@
1
1
  export { ConnectionType, IBattery, IBatteryOptions, IDeviceDetect, IDeviceDetectOptions, IGeolocation, IGeolocationCoordinates, IGeolocationOptions, IIdleOptions, IMediaQueryOptions, INetworkSpeed, INetworkSpeedOptions, IOnlineOptions, useBattery, useDeviceDetect, useGeolocation, useIdle, useMediaQuery, useNetworkSpeed, useOnline } from './browser/index.mjs';
2
+ export { IUseStorageOptions, IUseStorageReturn, StorageType, StorageValue, useStorage } from './storage/index.mjs';
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { ConnectionType, IBattery, IBatteryOptions, IDeviceDetect, IDeviceDetectOptions, IGeolocation, IGeolocationCoordinates, IGeolocationOptions, IIdleOptions, IMediaQueryOptions, INetworkSpeed, INetworkSpeedOptions, IOnlineOptions, useBattery, useDeviceDetect, useGeolocation, useIdle, useMediaQuery, useNetworkSpeed, useOnline } from './browser/index.js';
2
+ export { IUseStorageOptions, IUseStorageReturn, StorageType, StorageValue, useStorage } from './storage/index.js';
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkQCPNR33K_js = require('./chunk-QCPNR33K.js');
4
+ var chunk3QXSUE3X_js = require('./chunk-3QXSUE3X.js');
4
5
 
5
6
 
6
7
 
@@ -32,5 +33,9 @@ Object.defineProperty(exports, "useOnline", {
32
33
  enumerable: true,
33
34
  get: function () { return chunkQCPNR33K_js.useOnline; }
34
35
  });
36
+ Object.defineProperty(exports, "useStorage", {
37
+ enumerable: true,
38
+ get: function () { return chunk3QXSUE3X_js.useStorage; }
39
+ });
35
40
  //# sourceMappingURL=index.js.map
36
41
  //# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  export { useBattery, useDeviceDetect, useGeolocation, useIdle, useMediaQuery, useNetworkSpeed, useOnline } from './chunk-MWZHFSNO.mjs';
2
+ export { useStorage } from './chunk-3OHPGV6V.mjs';
2
3
  //# sourceMappingURL=index.mjs.map
3
4
  //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,26 @@
1
+ type StorageType = 'localStorage' | 'sessionStorage' | 'cookie';
2
+ type StorageValue = string | number | boolean | unknown[] | Record<string, unknown> | null;
3
+ interface IUseStorageOptions<T extends StorageValue = StorageValue> {
4
+ storageType?: StorageType;
5
+ defaultValue?: T;
6
+ sync?: boolean;
7
+ cookieOptions?: {
8
+ expires?: number;
9
+ path?: string;
10
+ domain?: string;
11
+ secure?: boolean;
12
+ sameSite?: 'Strict' | 'Lax' | 'None';
13
+ };
14
+ onChange?: (value: T | null) => void;
15
+ }
16
+ interface IUseStorageReturn<T extends StorageValue = StorageValue> {
17
+ value: T | null;
18
+ setValue: (value: T | null) => void;
19
+ removeValue: () => void;
20
+ hasValue: boolean;
21
+ clear: () => void;
22
+ }
23
+
24
+ declare function useStorage<T extends StorageValue = StorageValue>(key: string, options?: IUseStorageOptions<T>): IUseStorageReturn<T>;
25
+
26
+ export { type IUseStorageOptions, type IUseStorageReturn, type StorageType, type StorageValue, useStorage };
@@ -0,0 +1,26 @@
1
+ type StorageType = 'localStorage' | 'sessionStorage' | 'cookie';
2
+ type StorageValue = string | number | boolean | unknown[] | Record<string, unknown> | null;
3
+ interface IUseStorageOptions<T extends StorageValue = StorageValue> {
4
+ storageType?: StorageType;
5
+ defaultValue?: T;
6
+ sync?: boolean;
7
+ cookieOptions?: {
8
+ expires?: number;
9
+ path?: string;
10
+ domain?: string;
11
+ secure?: boolean;
12
+ sameSite?: 'Strict' | 'Lax' | 'None';
13
+ };
14
+ onChange?: (value: T | null) => void;
15
+ }
16
+ interface IUseStorageReturn<T extends StorageValue = StorageValue> {
17
+ value: T | null;
18
+ setValue: (value: T | null) => void;
19
+ removeValue: () => void;
20
+ hasValue: boolean;
21
+ clear: () => void;
22
+ }
23
+
24
+ declare function useStorage<T extends StorageValue = StorageValue>(key: string, options?: IUseStorageOptions<T>): IUseStorageReturn<T>;
25
+
26
+ export { type IUseStorageOptions, type IUseStorageReturn, type StorageType, type StorageValue, useStorage };
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var chunk3QXSUE3X_js = require('../chunk-3QXSUE3X.js');
4
+
5
+
6
+
7
+ Object.defineProperty(exports, "useStorage", {
8
+ enumerable: true,
9
+ get: function () { return chunk3QXSUE3X_js.useStorage; }
10
+ });
11
+ //# sourceMappingURL=index.js.map
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,3 @@
1
+ export { useStorage } from '../chunk-3OHPGV6V.mjs';
2
+ //# sourceMappingURL=index.mjs.map
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
package/package.json CHANGED
@@ -1,91 +1,96 @@
1
- {
2
- "name": "react-hooks-core",
3
- "version": "1.0.2",
4
- "description": "Production-ready React hooks library with TypeScript and SSR support",
5
- "main": "./dist/index.js",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.js"
13
- },
14
- "./browser": {
15
- "types": "./dist/browser/index.d.ts",
16
- "import": "./dist/browser/index.mjs",
17
- "require": "./dist/browser/index.js"
18
- }
19
- },
20
- "files": [
21
- "dist",
22
- "README.md",
23
- "LICENSE"
24
- ],
25
- "author": "NightDevilPT",
26
- "repository": {
27
- "type": "git",
28
- "url": "https://github.com/NightDevilPT/react-hooks-utils?tab=readme-ov-file"
29
- },
30
- "scripts": {
31
- "build": "tsup",
32
- "test": "jest",
33
- "lint": "eslint src",
34
- "type-check": "tsc --noEmit",
35
- "format": "prettier --write \"src/**/*.{ts,tsx}\"",
36
- "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
37
- "deploy": "npm publish",
38
- "deploy:patch": "npm run prepublishOnly && npm version patch && npm publish",
39
- "deploy:minor": "npm run prepublishOnly && npm version minor && npm publish",
40
- "deploy:major": "npm run prepublishOnly && npm version major && npm publish",
41
- "link": "npm run build && npm link",
42
- "prepublishOnly": "npm run test && npm run lint && npm run type-check && npm run format && npm run format:check && npm run build",
43
- "prepare": "husky"
44
- },
45
- "keywords": [
46
- "react",
47
- "hooks",
48
- "react-hooks",
49
- "nextjs",
50
- "typescript",
51
- "ssr",
52
- "device-detection",
53
- "browser-detection"
54
- ],
55
- "license": "MIT",
56
- "peerDependencies": {
57
- "react": "^19.2.3",
58
- "react-dom": "^19.2.3"
59
- },
60
- "devDependencies": {
61
- "@testing-library/jest-dom": "^6.9.1",
62
- "@testing-library/react": "^16.3.1",
63
- "@types/jest": "^30.0.0",
64
- "@types/node": "^25.0.3",
65
- "@types/react": "^19.2.7",
66
- "@types/react-dom": "^19.2.3",
67
- "@typescript-eslint/eslint-plugin": "^8.50.1",
68
- "@typescript-eslint/parser": "^8.50.1",
69
- "eslint": "^9.39.2",
70
- "eslint-plugin-react": "^7.37.5",
71
- "eslint-plugin-react-hooks": "^7.0.1",
72
- "globals": "^16.5.0",
73
- "husky": "^9.1.7",
74
- "jest-environment-jsdom": "^30.2.0",
75
- "lint-staged": "^16.2.7",
76
- "prettier": "^3.7.4",
77
- "rimraf": "^6.1.2",
78
- "ts-jest": "^29.4.6",
79
- "tsup": "^8.5.1",
80
- "typescript": "^5.9.3"
81
- },
82
- "dependencies": {
83
- "jest": "^30.2.0"
84
- },
85
- "lint-staged": {
86
- "src/**/*.{ts,tsx}": [
87
- "prettier --write",
88
- "eslint --fix"
89
- ]
90
- }
91
- }
1
+ {
2
+ "name": "react-hooks-core",
3
+ "version": "1.1.0",
4
+ "description": "Production-ready React hooks library with TypeScript and SSR support",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./browser": {
15
+ "types": "./dist/browser/index.d.ts",
16
+ "import": "./dist/browser/index.mjs",
17
+ "require": "./dist/browser/index.js"
18
+ },
19
+ "./storage": {
20
+ "types": "./dist/storage/index.d.ts",
21
+ "import": "./dist/storage/index.mjs",
22
+ "require": "./dist/storage/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "author": "NightDevilPT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/NightDevilPT/react-hooks-utils?tab=readme-ov-file"
34
+ },
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "test": "jest",
38
+ "lint": "eslint src",
39
+ "type-check": "tsc --noEmit",
40
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
41
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
42
+ "deploy": "npm publish",
43
+ "deploy:patch": "npm run prepublishOnly && npm version patch && npm publish",
44
+ "deploy:minor": "npm run prepublishOnly && npm publish",
45
+ "deploy:major": "npm run prepublishOnly && npm publish",
46
+ "link": "npm run build && npm link",
47
+ "prepublishOnly": "npm run test && npm run lint && npm run type-check && npm run format && npm run format:check && npm run build",
48
+ "prepare": "husky"
49
+ },
50
+ "keywords": [
51
+ "react",
52
+ "hooks",
53
+ "react-hooks",
54
+ "nextjs",
55
+ "typescript",
56
+ "ssr",
57
+ "device-detection",
58
+ "browser-detection"
59
+ ],
60
+ "license": "MIT",
61
+ "peerDependencies": {
62
+ "react": "^19.2.3",
63
+ "react-dom": "^19.2.3"
64
+ },
65
+ "devDependencies": {
66
+ "@testing-library/jest-dom": "^6.9.1",
67
+ "@testing-library/react": "^16.3.1",
68
+ "@types/jest": "^30.0.0",
69
+ "@types/node": "^25.0.3",
70
+ "@types/react": "^19.2.7",
71
+ "@types/react-dom": "^19.2.3",
72
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
73
+ "@typescript-eslint/parser": "^8.50.1",
74
+ "eslint": "^9.39.2",
75
+ "eslint-plugin-react": "^7.37.5",
76
+ "eslint-plugin-react-hooks": "^7.0.1",
77
+ "globals": "^16.5.0",
78
+ "husky": "^9.1.7",
79
+ "jest-environment-jsdom": "^30.2.0",
80
+ "lint-staged": "^16.2.7",
81
+ "prettier": "^3.7.4",
82
+ "rimraf": "^6.1.2",
83
+ "ts-jest": "^29.4.6",
84
+ "tsup": "^8.5.1",
85
+ "typescript": "^5.9.3"
86
+ },
87
+ "dependencies": {
88
+ "jest": "^30.2.0"
89
+ },
90
+ "lint-staged": {
91
+ "src/**/*.{ts,tsx}": [
92
+ "prettier --write",
93
+ "eslint --fix"
94
+ ]
95
+ }
96
+ }