@geekmidas/ui 0.1.0 → 1.0.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,5 @@
1
+ const require_hooks = require('../hooks-DuxmSO-h.cjs');
2
+
3
+ exports.useDebounce = require_hooks.useDebounce;
4
+ exports.useLocalStorage = require_hooks.useLocalStorage;
5
+ exports.useWebSocket = require_hooks.useWebSocket;
@@ -0,0 +1,2 @@
1
+ import { UseWebSocketOptions, UseWebSocketReturn, WebSocketStatus, useDebounce, useLocalStorage, useWebSocket } from "../index-QNnnyGjB.cjs";
2
+ export { UseWebSocketOptions, UseWebSocketReturn, WebSocketStatus, useDebounce, useLocalStorage, useWebSocket };
@@ -0,0 +1,2 @@
1
+ import { UseWebSocketOptions, UseWebSocketReturn, WebSocketStatus, useDebounce, useLocalStorage, useWebSocket } from "../index-DmtSyJ1q.mjs";
2
+ export { UseWebSocketOptions, UseWebSocketReturn, WebSocketStatus, useDebounce, useLocalStorage, useWebSocket };
@@ -0,0 +1,3 @@
1
+ import { useDebounce, useLocalStorage, useWebSocket } from "../hooks-DBc-Cw9X.mjs";
2
+
3
+ export { useDebounce, useLocalStorage, useWebSocket };
@@ -0,0 +1,206 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ //#region src/hooks/use-debounce.ts
4
+ /**
5
+ * Debounces a value by delaying updates until after a specified delay.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * const [search, setSearch] = useState('');
10
+ * const debouncedSearch = useDebounce(search, 300);
11
+ *
12
+ * useEffect(() => {
13
+ * // Only fires 300ms after user stops typing
14
+ * fetchResults(debouncedSearch);
15
+ * }, [debouncedSearch]);
16
+ * ```
17
+ */
18
+ function useDebounce(value, delay) {
19
+ const [debouncedValue, setDebouncedValue] = useState(value);
20
+ useEffect(() => {
21
+ const timer = setTimeout(() => {
22
+ setDebouncedValue(value);
23
+ }, delay);
24
+ return () => {
25
+ clearTimeout(timer);
26
+ };
27
+ }, [value, delay]);
28
+ return debouncedValue;
29
+ }
30
+
31
+ //#endregion
32
+ //#region src/hooks/use-local-storage.ts
33
+ /**
34
+ * Syncs state with localStorage, with SSR support.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * const [theme, setTheme] = useLocalStorage('theme', 'dark');
39
+ *
40
+ * // Value persists across page reloads
41
+ * setTheme('light');
42
+ * ```
43
+ */
44
+ function useLocalStorage(key, initialValue) {
45
+ const readValue = useCallback(() => {
46
+ if (typeof window === "undefined") return initialValue;
47
+ try {
48
+ const item = window.localStorage.getItem(key);
49
+ return item ? JSON.parse(item) : initialValue;
50
+ } catch (_error) {
51
+ return initialValue;
52
+ }
53
+ }, [initialValue, key]);
54
+ const [storedValue, setStoredValue] = useState(readValue);
55
+ useEffect(() => {
56
+ setStoredValue(readValue());
57
+ }, [readValue]);
58
+ useEffect(() => {
59
+ const handleStorageChange = (event) => {
60
+ if (event.key === key && event.newValue !== null) try {
61
+ setStoredValue(JSON.parse(event.newValue));
62
+ } catch {
63
+ setStoredValue(event.newValue);
64
+ }
65
+ };
66
+ window.addEventListener("storage", handleStorageChange);
67
+ return () => window.removeEventListener("storage", handleStorageChange);
68
+ }, [key]);
69
+ const setValue = useCallback((value) => {
70
+ try {
71
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
72
+ setStoredValue(valueToStore);
73
+ if (typeof window !== "undefined") {
74
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
75
+ window.dispatchEvent(new StorageEvent("storage", {
76
+ key,
77
+ newValue: JSON.stringify(valueToStore)
78
+ }));
79
+ }
80
+ } catch (_error) {}
81
+ }, [key, storedValue]);
82
+ const removeValue = useCallback(() => {
83
+ try {
84
+ if (typeof window !== "undefined") {
85
+ window.localStorage.removeItem(key);
86
+ setStoredValue(initialValue);
87
+ }
88
+ } catch (_error) {}
89
+ }, [key, initialValue]);
90
+ return [
91
+ storedValue,
92
+ setValue,
93
+ removeValue
94
+ ];
95
+ }
96
+
97
+ //#endregion
98
+ //#region src/hooks/use-websocket.ts
99
+ /**
100
+ * Hook for managing WebSocket connections with auto-reconnect.
101
+ *
102
+ * @example
103
+ * ```tsx
104
+ * const { status, lastMessage, send } = useWebSocket<LogEntry>(
105
+ * 'ws://localhost:3000/ws',
106
+ * {
107
+ * onMessage: (event) => console.log('Received:', event.data),
108
+ * }
109
+ * );
110
+ *
111
+ * // Send a message
112
+ * send({ type: 'subscribe', channel: 'logs' });
113
+ *
114
+ * // Check connection status
115
+ * if (status === 'connected') {
116
+ * // ...
117
+ * }
118
+ * ```
119
+ */
120
+ function useWebSocket(url, options = {}) {
121
+ const { reconnect = true, reconnectDelay = 3e3, maxReconnectAttempts = 5, onOpen, onClose, onError, onMessage } = options;
122
+ const [status, setStatus] = useState("disconnected");
123
+ const [lastMessage, setLastMessage] = useState(null);
124
+ const wsRef = useRef(null);
125
+ const reconnectAttemptsRef = useRef(0);
126
+ const reconnectTimeoutRef = useRef(null);
127
+ const connect = useCallback(() => {
128
+ if (!url || wsRef.current?.readyState === WebSocket.OPEN) return;
129
+ if (wsRef.current) wsRef.current.close();
130
+ setStatus("connecting");
131
+ const ws = new WebSocket(url);
132
+ ws.onopen = (event) => {
133
+ setStatus("connected");
134
+ reconnectAttemptsRef.current = 0;
135
+ onOpen?.(event);
136
+ };
137
+ ws.onclose = (event) => {
138
+ setStatus("disconnected");
139
+ onClose?.(event);
140
+ if (reconnect && !event.wasClean && reconnectAttemptsRef.current < maxReconnectAttempts) {
141
+ reconnectAttemptsRef.current += 1;
142
+ reconnectTimeoutRef.current = setTimeout(() => {
143
+ connect();
144
+ }, reconnectDelay);
145
+ }
146
+ };
147
+ ws.onerror = (event) => {
148
+ onError?.(event);
149
+ };
150
+ ws.onmessage = (event) => {
151
+ try {
152
+ const data = JSON.parse(event.data);
153
+ setLastMessage(data);
154
+ } catch {
155
+ setLastMessage(event.data);
156
+ }
157
+ onMessage?.(event);
158
+ };
159
+ wsRef.current = ws;
160
+ }, [
161
+ url,
162
+ reconnect,
163
+ reconnectDelay,
164
+ maxReconnectAttempts,
165
+ onOpen,
166
+ onClose,
167
+ onError,
168
+ onMessage
169
+ ]);
170
+ const disconnect = useCallback(() => {
171
+ if (reconnectTimeoutRef.current) {
172
+ clearTimeout(reconnectTimeoutRef.current);
173
+ reconnectTimeoutRef.current = null;
174
+ }
175
+ if (wsRef.current) {
176
+ wsRef.current.close(1e3, "Manual disconnect");
177
+ wsRef.current = null;
178
+ }
179
+ reconnectAttemptsRef.current = maxReconnectAttempts;
180
+ setStatus("disconnected");
181
+ }, [maxReconnectAttempts]);
182
+ const send = useCallback((data) => {
183
+ if (wsRef.current?.readyState === WebSocket.OPEN) {
184
+ const message = typeof data === "string" ? data : JSON.stringify(data);
185
+ wsRef.current.send(message);
186
+ }
187
+ }, []);
188
+ useEffect(() => {
189
+ if (url) connect();
190
+ return () => {
191
+ if (reconnectTimeoutRef.current) clearTimeout(reconnectTimeoutRef.current);
192
+ if (wsRef.current) wsRef.current.close(1e3, "Component unmount");
193
+ };
194
+ }, [url, connect]);
195
+ return {
196
+ status,
197
+ lastMessage,
198
+ send,
199
+ connect,
200
+ disconnect
201
+ };
202
+ }
203
+
204
+ //#endregion
205
+ export { useDebounce, useLocalStorage, useWebSocket };
206
+ //# sourceMappingURL=hooks-DBc-Cw9X.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-DBc-Cw9X.mjs","names":["value: T","delay: number","key: string","initialValue: T","event: StorageEvent","value: T | ((prev: T) => T)","url: string | null","options: UseWebSocketOptions","data: string | object"],"sources":["../src/hooks/use-debounce.ts","../src/hooks/use-local-storage.ts","../src/hooks/use-websocket.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Debounces a value by delaying updates until after a specified delay.\n *\n * @example\n * ```tsx\n * const [search, setSearch] = useState('');\n * const debouncedSearch = useDebounce(search, 300);\n *\n * useEffect(() => {\n * // Only fires 300ms after user stops typing\n * fetchResults(debouncedSearch);\n * }, [debouncedSearch]);\n * ```\n */\nexport function useDebounce<T>(value: T, delay: number): T {\n\tconst [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsetDebouncedValue(value);\n\t\t}, delay);\n\n\t\treturn () => {\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, [value, delay]);\n\n\treturn debouncedValue;\n}\n\nexport default useDebounce;\n","import { useCallback, useEffect, useState } from 'react';\n\n/**\n * Syncs state with localStorage, with SSR support.\n *\n * @example\n * ```tsx\n * const [theme, setTheme] = useLocalStorage('theme', 'dark');\n *\n * // Value persists across page reloads\n * setTheme('light');\n * ```\n */\nexport function useLocalStorage<T>(\n\tkey: string,\n\tinitialValue: T,\n): [T, (value: T | ((prev: T) => T)) => void, () => void] {\n\t// Get initial value from localStorage or use provided initial value\n\tconst readValue = useCallback((): T => {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn initialValue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst item = window.localStorage.getItem(key);\n\t\t\treturn item ? (JSON.parse(item) as T) : initialValue;\n\t\t} catch (_error) {\n\t\t\treturn initialValue;\n\t\t}\n\t}, [initialValue, key]);\n\n\tconst [storedValue, setStoredValue] = useState<T>(readValue);\n\n\t// Update state when key changes\n\tuseEffect(() => {\n\t\tsetStoredValue(readValue());\n\t}, [readValue]);\n\n\t// Listen for storage changes from other tabs/windows\n\tuseEffect(() => {\n\t\tconst handleStorageChange = (event: StorageEvent) => {\n\t\t\tif (event.key === key && event.newValue !== null) {\n\t\t\t\ttry {\n\t\t\t\t\tsetStoredValue(JSON.parse(event.newValue) as T);\n\t\t\t\t} catch {\n\t\t\t\t\tsetStoredValue(event.newValue as unknown as T);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener('storage', handleStorageChange);\n\t\treturn () => window.removeEventListener('storage', handleStorageChange);\n\t}, [key]);\n\n\t// Setter that also updates localStorage\n\tconst setValue = useCallback(\n\t\t(value: T | ((prev: T) => T)) => {\n\t\t\ttry {\n\t\t\t\t// Allow value to be a function for functional updates\n\t\t\t\tconst valueToStore =\n\t\t\t\t\tvalue instanceof Function ? value(storedValue) : value;\n\n\t\t\t\tsetStoredValue(valueToStore);\n\n\t\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\t\twindow.localStorage.setItem(key, JSON.stringify(valueToStore));\n\n\t\t\t\t\t// Dispatch event for other components using the same key\n\t\t\t\t\twindow.dispatchEvent(\n\t\t\t\t\t\tnew StorageEvent('storage', {\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tnewValue: JSON.stringify(valueToStore),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (_error) {}\n\t\t},\n\t\t[key, storedValue],\n\t);\n\n\t// Remove value from localStorage\n\tconst removeValue = useCallback(() => {\n\t\ttry {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.localStorage.removeItem(key);\n\t\t\t\tsetStoredValue(initialValue);\n\t\t\t}\n\t\t} catch (_error) {}\n\t}, [key, initialValue]);\n\n\treturn [storedValue, setValue, removeValue];\n}\n\nexport default useLocalStorage;\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport type WebSocketStatus = 'connecting' | 'connected' | 'disconnected';\n\nexport interface UseWebSocketOptions {\n\t/**\n\t * Automatically reconnect on disconnect.\n\t * @default true\n\t */\n\treconnect?: boolean;\n\t/**\n\t * Reconnection delay in milliseconds.\n\t * @default 3000\n\t */\n\treconnectDelay?: number;\n\t/**\n\t * Maximum reconnection attempts.\n\t * @default 5\n\t */\n\tmaxReconnectAttempts?: number;\n\t/**\n\t * Callback when connection opens.\n\t */\n\tonOpen?: (event: Event) => void;\n\t/**\n\t * Callback when connection closes.\n\t */\n\tonClose?: (event: CloseEvent) => void;\n\t/**\n\t * Callback when an error occurs.\n\t */\n\tonError?: (event: Event) => void;\n\t/**\n\t * Callback when a message is received.\n\t */\n\tonMessage?: (event: MessageEvent) => void;\n}\n\nexport interface UseWebSocketReturn<T = unknown> {\n\t/**\n\t * Current connection status.\n\t */\n\tstatus: WebSocketStatus;\n\t/**\n\t * Last received message (parsed as JSON if possible).\n\t */\n\tlastMessage: T | null;\n\t/**\n\t * Send a message through the WebSocket.\n\t */\n\tsend: (data: string | object) => void;\n\t/**\n\t * Manually connect to the WebSocket.\n\t */\n\tconnect: () => void;\n\t/**\n\t * Manually disconnect from the WebSocket.\n\t */\n\tdisconnect: () => void;\n}\n\n/**\n * Hook for managing WebSocket connections with auto-reconnect.\n *\n * @example\n * ```tsx\n * const { status, lastMessage, send } = useWebSocket<LogEntry>(\n * 'ws://localhost:3000/ws',\n * {\n * onMessage: (event) => console.log('Received:', event.data),\n * }\n * );\n *\n * // Send a message\n * send({ type: 'subscribe', channel: 'logs' });\n *\n * // Check connection status\n * if (status === 'connected') {\n * // ...\n * }\n * ```\n */\nexport function useWebSocket<T = unknown>(\n\turl: string | null,\n\toptions: UseWebSocketOptions = {},\n): UseWebSocketReturn<T> {\n\tconst {\n\t\treconnect = true,\n\t\treconnectDelay = 3000,\n\t\tmaxReconnectAttempts = 5,\n\t\tonOpen,\n\t\tonClose,\n\t\tonError,\n\t\tonMessage,\n\t} = options;\n\n\tconst [status, setStatus] = useState<WebSocketStatus>('disconnected');\n\tconst [lastMessage, setLastMessage] = useState<T | null>(null);\n\n\tconst wsRef = useRef<WebSocket | null>(null);\n\tconst reconnectAttemptsRef = useRef(0);\n\tconst reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\tnull,\n\t);\n\n\tconst connect = useCallback(() => {\n\t\tif (!url || wsRef.current?.readyState === WebSocket.OPEN) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up existing connection\n\t\tif (wsRef.current) {\n\t\t\twsRef.current.close();\n\t\t}\n\n\t\tsetStatus('connecting');\n\n\t\tconst ws = new WebSocket(url);\n\n\t\tws.onopen = (event) => {\n\t\t\tsetStatus('connected');\n\t\t\treconnectAttemptsRef.current = 0;\n\t\t\tonOpen?.(event);\n\t\t};\n\n\t\tws.onclose = (event) => {\n\t\t\tsetStatus('disconnected');\n\t\t\tonClose?.(event);\n\n\t\t\t// Attempt reconnection if enabled\n\t\t\tif (\n\t\t\t\treconnect &&\n\t\t\t\t!event.wasClean &&\n\t\t\t\treconnectAttemptsRef.current < maxReconnectAttempts\n\t\t\t) {\n\t\t\t\treconnectAttemptsRef.current += 1;\n\t\t\t\treconnectTimeoutRef.current = setTimeout(() => {\n\t\t\t\t\tconnect();\n\t\t\t\t}, reconnectDelay);\n\t\t\t}\n\t\t};\n\n\t\tws.onerror = (event) => {\n\t\t\tonError?.(event);\n\t\t};\n\n\t\tws.onmessage = (event) => {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(event.data) as T;\n\t\t\t\tsetLastMessage(data);\n\t\t\t} catch {\n\t\t\t\tsetLastMessage(event.data as unknown as T);\n\t\t\t}\n\t\t\tonMessage?.(event);\n\t\t};\n\n\t\twsRef.current = ws;\n\t}, [\n\t\turl,\n\t\treconnect,\n\t\treconnectDelay,\n\t\tmaxReconnectAttempts,\n\t\tonOpen,\n\t\tonClose,\n\t\tonError,\n\t\tonMessage,\n\t]);\n\n\tconst disconnect = useCallback(() => {\n\t\tif (reconnectTimeoutRef.current) {\n\t\t\tclearTimeout(reconnectTimeoutRef.current);\n\t\t\treconnectTimeoutRef.current = null;\n\t\t}\n\n\t\tif (wsRef.current) {\n\t\t\twsRef.current.close(1000, 'Manual disconnect');\n\t\t\twsRef.current = null;\n\t\t}\n\n\t\treconnectAttemptsRef.current = maxReconnectAttempts; // Prevent auto-reconnect\n\t\tsetStatus('disconnected');\n\t}, [maxReconnectAttempts]);\n\n\tconst send = useCallback((data: string | object) => {\n\t\tif (wsRef.current?.readyState === WebSocket.OPEN) {\n\t\t\tconst message = typeof data === 'string' ? data : JSON.stringify(data);\n\t\t\twsRef.current.send(message);\n\t\t} else {\n\t\t}\n\t}, []);\n\n\t// Connect on mount if URL is provided\n\tuseEffect(() => {\n\t\tif (url) {\n\t\t\tconnect();\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (reconnectTimeoutRef.current) {\n\t\t\t\tclearTimeout(reconnectTimeoutRef.current);\n\t\t\t}\n\t\t\tif (wsRef.current) {\n\t\t\t\twsRef.current.close(1000, 'Component unmount');\n\t\t\t}\n\t\t};\n\t}, [url, connect]);\n\n\treturn {\n\t\tstatus,\n\t\tlastMessage,\n\t\tsend,\n\t\tconnect,\n\t\tdisconnect,\n\t};\n}\n\nexport default useWebSocket;\n"],"mappings":"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"}
@@ -0,0 +1,252 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const react = __toESM(require("react"));
25
+
26
+ //#region src/hooks/use-debounce.ts
27
+ /**
28
+ * Debounces a value by delaying updates until after a specified delay.
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * const [search, setSearch] = useState('');
33
+ * const debouncedSearch = useDebounce(search, 300);
34
+ *
35
+ * useEffect(() => {
36
+ * // Only fires 300ms after user stops typing
37
+ * fetchResults(debouncedSearch);
38
+ * }, [debouncedSearch]);
39
+ * ```
40
+ */
41
+ function useDebounce(value, delay) {
42
+ const [debouncedValue, setDebouncedValue] = (0, react.useState)(value);
43
+ (0, react.useEffect)(() => {
44
+ const timer = setTimeout(() => {
45
+ setDebouncedValue(value);
46
+ }, delay);
47
+ return () => {
48
+ clearTimeout(timer);
49
+ };
50
+ }, [value, delay]);
51
+ return debouncedValue;
52
+ }
53
+
54
+ //#endregion
55
+ //#region src/hooks/use-local-storage.ts
56
+ /**
57
+ * Syncs state with localStorage, with SSR support.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const [theme, setTheme] = useLocalStorage('theme', 'dark');
62
+ *
63
+ * // Value persists across page reloads
64
+ * setTheme('light');
65
+ * ```
66
+ */
67
+ function useLocalStorage(key, initialValue) {
68
+ const readValue = (0, react.useCallback)(() => {
69
+ if (typeof window === "undefined") return initialValue;
70
+ try {
71
+ const item = window.localStorage.getItem(key);
72
+ return item ? JSON.parse(item) : initialValue;
73
+ } catch (_error) {
74
+ return initialValue;
75
+ }
76
+ }, [initialValue, key]);
77
+ const [storedValue, setStoredValue] = (0, react.useState)(readValue);
78
+ (0, react.useEffect)(() => {
79
+ setStoredValue(readValue());
80
+ }, [readValue]);
81
+ (0, react.useEffect)(() => {
82
+ const handleStorageChange = (event) => {
83
+ if (event.key === key && event.newValue !== null) try {
84
+ setStoredValue(JSON.parse(event.newValue));
85
+ } catch {
86
+ setStoredValue(event.newValue);
87
+ }
88
+ };
89
+ window.addEventListener("storage", handleStorageChange);
90
+ return () => window.removeEventListener("storage", handleStorageChange);
91
+ }, [key]);
92
+ const setValue = (0, react.useCallback)((value) => {
93
+ try {
94
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
95
+ setStoredValue(valueToStore);
96
+ if (typeof window !== "undefined") {
97
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
98
+ window.dispatchEvent(new StorageEvent("storage", {
99
+ key,
100
+ newValue: JSON.stringify(valueToStore)
101
+ }));
102
+ }
103
+ } catch (_error) {}
104
+ }, [key, storedValue]);
105
+ const removeValue = (0, react.useCallback)(() => {
106
+ try {
107
+ if (typeof window !== "undefined") {
108
+ window.localStorage.removeItem(key);
109
+ setStoredValue(initialValue);
110
+ }
111
+ } catch (_error) {}
112
+ }, [key, initialValue]);
113
+ return [
114
+ storedValue,
115
+ setValue,
116
+ removeValue
117
+ ];
118
+ }
119
+
120
+ //#endregion
121
+ //#region src/hooks/use-websocket.ts
122
+ /**
123
+ * Hook for managing WebSocket connections with auto-reconnect.
124
+ *
125
+ * @example
126
+ * ```tsx
127
+ * const { status, lastMessage, send } = useWebSocket<LogEntry>(
128
+ * 'ws://localhost:3000/ws',
129
+ * {
130
+ * onMessage: (event) => console.log('Received:', event.data),
131
+ * }
132
+ * );
133
+ *
134
+ * // Send a message
135
+ * send({ type: 'subscribe', channel: 'logs' });
136
+ *
137
+ * // Check connection status
138
+ * if (status === 'connected') {
139
+ * // ...
140
+ * }
141
+ * ```
142
+ */
143
+ function useWebSocket(url, options = {}) {
144
+ const { reconnect = true, reconnectDelay = 3e3, maxReconnectAttempts = 5, onOpen, onClose, onError, onMessage } = options;
145
+ const [status, setStatus] = (0, react.useState)("disconnected");
146
+ const [lastMessage, setLastMessage] = (0, react.useState)(null);
147
+ const wsRef = (0, react.useRef)(null);
148
+ const reconnectAttemptsRef = (0, react.useRef)(0);
149
+ const reconnectTimeoutRef = (0, react.useRef)(null);
150
+ const connect = (0, react.useCallback)(() => {
151
+ if (!url || wsRef.current?.readyState === WebSocket.OPEN) return;
152
+ if (wsRef.current) wsRef.current.close();
153
+ setStatus("connecting");
154
+ const ws = new WebSocket(url);
155
+ ws.onopen = (event) => {
156
+ setStatus("connected");
157
+ reconnectAttemptsRef.current = 0;
158
+ onOpen?.(event);
159
+ };
160
+ ws.onclose = (event) => {
161
+ setStatus("disconnected");
162
+ onClose?.(event);
163
+ if (reconnect && !event.wasClean && reconnectAttemptsRef.current < maxReconnectAttempts) {
164
+ reconnectAttemptsRef.current += 1;
165
+ reconnectTimeoutRef.current = setTimeout(() => {
166
+ connect();
167
+ }, reconnectDelay);
168
+ }
169
+ };
170
+ ws.onerror = (event) => {
171
+ onError?.(event);
172
+ };
173
+ ws.onmessage = (event) => {
174
+ try {
175
+ const data = JSON.parse(event.data);
176
+ setLastMessage(data);
177
+ } catch {
178
+ setLastMessage(event.data);
179
+ }
180
+ onMessage?.(event);
181
+ };
182
+ wsRef.current = ws;
183
+ }, [
184
+ url,
185
+ reconnect,
186
+ reconnectDelay,
187
+ maxReconnectAttempts,
188
+ onOpen,
189
+ onClose,
190
+ onError,
191
+ onMessage
192
+ ]);
193
+ const disconnect = (0, react.useCallback)(() => {
194
+ if (reconnectTimeoutRef.current) {
195
+ clearTimeout(reconnectTimeoutRef.current);
196
+ reconnectTimeoutRef.current = null;
197
+ }
198
+ if (wsRef.current) {
199
+ wsRef.current.close(1e3, "Manual disconnect");
200
+ wsRef.current = null;
201
+ }
202
+ reconnectAttemptsRef.current = maxReconnectAttempts;
203
+ setStatus("disconnected");
204
+ }, [maxReconnectAttempts]);
205
+ const send = (0, react.useCallback)((data) => {
206
+ if (wsRef.current?.readyState === WebSocket.OPEN) {
207
+ const message = typeof data === "string" ? data : JSON.stringify(data);
208
+ wsRef.current.send(message);
209
+ }
210
+ }, []);
211
+ (0, react.useEffect)(() => {
212
+ if (url) connect();
213
+ return () => {
214
+ if (reconnectTimeoutRef.current) clearTimeout(reconnectTimeoutRef.current);
215
+ if (wsRef.current) wsRef.current.close(1e3, "Component unmount");
216
+ };
217
+ }, [url, connect]);
218
+ return {
219
+ status,
220
+ lastMessage,
221
+ send,
222
+ connect,
223
+ disconnect
224
+ };
225
+ }
226
+
227
+ //#endregion
228
+ Object.defineProperty(exports, '__toESM', {
229
+ enumerable: true,
230
+ get: function () {
231
+ return __toESM;
232
+ }
233
+ });
234
+ Object.defineProperty(exports, 'useDebounce', {
235
+ enumerable: true,
236
+ get: function () {
237
+ return useDebounce;
238
+ }
239
+ });
240
+ Object.defineProperty(exports, 'useLocalStorage', {
241
+ enumerable: true,
242
+ get: function () {
243
+ return useLocalStorage;
244
+ }
245
+ });
246
+ Object.defineProperty(exports, 'useWebSocket', {
247
+ enumerable: true,
248
+ get: function () {
249
+ return useWebSocket;
250
+ }
251
+ });
252
+ //# sourceMappingURL=hooks-DuxmSO-h.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-DuxmSO-h.cjs","names":["value: T","delay: number","key: string","initialValue: T","event: StorageEvent","value: T | ((prev: T) => T)","url: string | null","options: UseWebSocketOptions","data: string | object"],"sources":["../src/hooks/use-debounce.ts","../src/hooks/use-local-storage.ts","../src/hooks/use-websocket.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Debounces a value by delaying updates until after a specified delay.\n *\n * @example\n * ```tsx\n * const [search, setSearch] = useState('');\n * const debouncedSearch = useDebounce(search, 300);\n *\n * useEffect(() => {\n * // Only fires 300ms after user stops typing\n * fetchResults(debouncedSearch);\n * }, [debouncedSearch]);\n * ```\n */\nexport function useDebounce<T>(value: T, delay: number): T {\n\tconst [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsetDebouncedValue(value);\n\t\t}, delay);\n\n\t\treturn () => {\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, [value, delay]);\n\n\treturn debouncedValue;\n}\n\nexport default useDebounce;\n","import { useCallback, useEffect, useState } from 'react';\n\n/**\n * Syncs state with localStorage, with SSR support.\n *\n * @example\n * ```tsx\n * const [theme, setTheme] = useLocalStorage('theme', 'dark');\n *\n * // Value persists across page reloads\n * setTheme('light');\n * ```\n */\nexport function useLocalStorage<T>(\n\tkey: string,\n\tinitialValue: T,\n): [T, (value: T | ((prev: T) => T)) => void, () => void] {\n\t// Get initial value from localStorage or use provided initial value\n\tconst readValue = useCallback((): T => {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn initialValue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst item = window.localStorage.getItem(key);\n\t\t\treturn item ? (JSON.parse(item) as T) : initialValue;\n\t\t} catch (_error) {\n\t\t\treturn initialValue;\n\t\t}\n\t}, [initialValue, key]);\n\n\tconst [storedValue, setStoredValue] = useState<T>(readValue);\n\n\t// Update state when key changes\n\tuseEffect(() => {\n\t\tsetStoredValue(readValue());\n\t}, [readValue]);\n\n\t// Listen for storage changes from other tabs/windows\n\tuseEffect(() => {\n\t\tconst handleStorageChange = (event: StorageEvent) => {\n\t\t\tif (event.key === key && event.newValue !== null) {\n\t\t\t\ttry {\n\t\t\t\t\tsetStoredValue(JSON.parse(event.newValue) as T);\n\t\t\t\t} catch {\n\t\t\t\t\tsetStoredValue(event.newValue as unknown as T);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener('storage', handleStorageChange);\n\t\treturn () => window.removeEventListener('storage', handleStorageChange);\n\t}, [key]);\n\n\t// Setter that also updates localStorage\n\tconst setValue = useCallback(\n\t\t(value: T | ((prev: T) => T)) => {\n\t\t\ttry {\n\t\t\t\t// Allow value to be a function for functional updates\n\t\t\t\tconst valueToStore =\n\t\t\t\t\tvalue instanceof Function ? value(storedValue) : value;\n\n\t\t\t\tsetStoredValue(valueToStore);\n\n\t\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\t\twindow.localStorage.setItem(key, JSON.stringify(valueToStore));\n\n\t\t\t\t\t// Dispatch event for other components using the same key\n\t\t\t\t\twindow.dispatchEvent(\n\t\t\t\t\t\tnew StorageEvent('storage', {\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tnewValue: JSON.stringify(valueToStore),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (_error) {}\n\t\t},\n\t\t[key, storedValue],\n\t);\n\n\t// Remove value from localStorage\n\tconst removeValue = useCallback(() => {\n\t\ttry {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.localStorage.removeItem(key);\n\t\t\t\tsetStoredValue(initialValue);\n\t\t\t}\n\t\t} catch (_error) {}\n\t}, [key, initialValue]);\n\n\treturn [storedValue, setValue, removeValue];\n}\n\nexport default useLocalStorage;\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport type WebSocketStatus = 'connecting' | 'connected' | 'disconnected';\n\nexport interface UseWebSocketOptions {\n\t/**\n\t * Automatically reconnect on disconnect.\n\t * @default true\n\t */\n\treconnect?: boolean;\n\t/**\n\t * Reconnection delay in milliseconds.\n\t * @default 3000\n\t */\n\treconnectDelay?: number;\n\t/**\n\t * Maximum reconnection attempts.\n\t * @default 5\n\t */\n\tmaxReconnectAttempts?: number;\n\t/**\n\t * Callback when connection opens.\n\t */\n\tonOpen?: (event: Event) => void;\n\t/**\n\t * Callback when connection closes.\n\t */\n\tonClose?: (event: CloseEvent) => void;\n\t/**\n\t * Callback when an error occurs.\n\t */\n\tonError?: (event: Event) => void;\n\t/**\n\t * Callback when a message is received.\n\t */\n\tonMessage?: (event: MessageEvent) => void;\n}\n\nexport interface UseWebSocketReturn<T = unknown> {\n\t/**\n\t * Current connection status.\n\t */\n\tstatus: WebSocketStatus;\n\t/**\n\t * Last received message (parsed as JSON if possible).\n\t */\n\tlastMessage: T | null;\n\t/**\n\t * Send a message through the WebSocket.\n\t */\n\tsend: (data: string | object) => void;\n\t/**\n\t * Manually connect to the WebSocket.\n\t */\n\tconnect: () => void;\n\t/**\n\t * Manually disconnect from the WebSocket.\n\t */\n\tdisconnect: () => void;\n}\n\n/**\n * Hook for managing WebSocket connections with auto-reconnect.\n *\n * @example\n * ```tsx\n * const { status, lastMessage, send } = useWebSocket<LogEntry>(\n * 'ws://localhost:3000/ws',\n * {\n * onMessage: (event) => console.log('Received:', event.data),\n * }\n * );\n *\n * // Send a message\n * send({ type: 'subscribe', channel: 'logs' });\n *\n * // Check connection status\n * if (status === 'connected') {\n * // ...\n * }\n * ```\n */\nexport function useWebSocket<T = unknown>(\n\turl: string | null,\n\toptions: UseWebSocketOptions = {},\n): UseWebSocketReturn<T> {\n\tconst {\n\t\treconnect = true,\n\t\treconnectDelay = 3000,\n\t\tmaxReconnectAttempts = 5,\n\t\tonOpen,\n\t\tonClose,\n\t\tonError,\n\t\tonMessage,\n\t} = options;\n\n\tconst [status, setStatus] = useState<WebSocketStatus>('disconnected');\n\tconst [lastMessage, setLastMessage] = useState<T | null>(null);\n\n\tconst wsRef = useRef<WebSocket | null>(null);\n\tconst reconnectAttemptsRef = useRef(0);\n\tconst reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\tnull,\n\t);\n\n\tconst connect = useCallback(() => {\n\t\tif (!url || wsRef.current?.readyState === WebSocket.OPEN) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up existing connection\n\t\tif (wsRef.current) {\n\t\t\twsRef.current.close();\n\t\t}\n\n\t\tsetStatus('connecting');\n\n\t\tconst ws = new WebSocket(url);\n\n\t\tws.onopen = (event) => {\n\t\t\tsetStatus('connected');\n\t\t\treconnectAttemptsRef.current = 0;\n\t\t\tonOpen?.(event);\n\t\t};\n\n\t\tws.onclose = (event) => {\n\t\t\tsetStatus('disconnected');\n\t\t\tonClose?.(event);\n\n\t\t\t// Attempt reconnection if enabled\n\t\t\tif (\n\t\t\t\treconnect &&\n\t\t\t\t!event.wasClean &&\n\t\t\t\treconnectAttemptsRef.current < maxReconnectAttempts\n\t\t\t) {\n\t\t\t\treconnectAttemptsRef.current += 1;\n\t\t\t\treconnectTimeoutRef.current = setTimeout(() => {\n\t\t\t\t\tconnect();\n\t\t\t\t}, reconnectDelay);\n\t\t\t}\n\t\t};\n\n\t\tws.onerror = (event) => {\n\t\t\tonError?.(event);\n\t\t};\n\n\t\tws.onmessage = (event) => {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(event.data) as T;\n\t\t\t\tsetLastMessage(data);\n\t\t\t} catch {\n\t\t\t\tsetLastMessage(event.data as unknown as T);\n\t\t\t}\n\t\t\tonMessage?.(event);\n\t\t};\n\n\t\twsRef.current = ws;\n\t}, [\n\t\turl,\n\t\treconnect,\n\t\treconnectDelay,\n\t\tmaxReconnectAttempts,\n\t\tonOpen,\n\t\tonClose,\n\t\tonError,\n\t\tonMessage,\n\t]);\n\n\tconst disconnect = useCallback(() => {\n\t\tif (reconnectTimeoutRef.current) {\n\t\t\tclearTimeout(reconnectTimeoutRef.current);\n\t\t\treconnectTimeoutRef.current = null;\n\t\t}\n\n\t\tif (wsRef.current) {\n\t\t\twsRef.current.close(1000, 'Manual disconnect');\n\t\t\twsRef.current = null;\n\t\t}\n\n\t\treconnectAttemptsRef.current = maxReconnectAttempts; // Prevent auto-reconnect\n\t\tsetStatus('disconnected');\n\t}, [maxReconnectAttempts]);\n\n\tconst send = useCallback((data: string | object) => {\n\t\tif (wsRef.current?.readyState === WebSocket.OPEN) {\n\t\t\tconst message = typeof data === 'string' ? data : JSON.stringify(data);\n\t\t\twsRef.current.send(message);\n\t\t} else {\n\t\t}\n\t}, []);\n\n\t// Connect on mount if URL is provided\n\tuseEffect(() => {\n\t\tif (url) {\n\t\t\tconnect();\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (reconnectTimeoutRef.current) {\n\t\t\t\tclearTimeout(reconnectTimeoutRef.current);\n\t\t\t}\n\t\t\tif (wsRef.current) {\n\t\t\t\twsRef.current.close(1000, 'Component unmount');\n\t\t\t}\n\t\t};\n\t}, [url, connect]);\n\n\treturn {\n\t\tstatus,\n\t\tlastMessage,\n\t\tsend,\n\t\tconnect,\n\t\tdisconnect,\n\t};\n}\n\nexport default useWebSocket;\n"],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ //#region src/hooks/use-debounce.d.ts
2
+ /**
3
+ * Debounces a value by delaying updates until after a specified delay.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * const [search, setSearch] = useState('');
8
+ * const debouncedSearch = useDebounce(search, 300);
9
+ *
10
+ * useEffect(() => {
11
+ * // Only fires 300ms after user stops typing
12
+ * fetchResults(debouncedSearch);
13
+ * }, [debouncedSearch]);
14
+ * ```
15
+ */
16
+ declare function useDebounce<T>(value: T, delay: number): T;
17
+ //#endregion
18
+ //#region src/hooks/use-local-storage.d.ts
19
+ /**
20
+ * Syncs state with localStorage, with SSR support.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const [theme, setTheme] = useLocalStorage('theme', 'dark');
25
+ *
26
+ * // Value persists across page reloads
27
+ * setTheme('light');
28
+ * ```
29
+ */
30
+ declare function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void, () => void];
31
+ //#endregion
32
+ //#region src/hooks/use-websocket.d.ts
33
+ type WebSocketStatus = 'connecting' | 'connected' | 'disconnected';
34
+ interface UseWebSocketOptions {
35
+ /**
36
+ * Automatically reconnect on disconnect.
37
+ * @default true
38
+ */
39
+ reconnect?: boolean;
40
+ /**
41
+ * Reconnection delay in milliseconds.
42
+ * @default 3000
43
+ */
44
+ reconnectDelay?: number;
45
+ /**
46
+ * Maximum reconnection attempts.
47
+ * @default 5
48
+ */
49
+ maxReconnectAttempts?: number;
50
+ /**
51
+ * Callback when connection opens.
52
+ */
53
+ onOpen?: (event: Event) => void;
54
+ /**
55
+ * Callback when connection closes.
56
+ */
57
+ onClose?: (event: CloseEvent) => void;
58
+ /**
59
+ * Callback when an error occurs.
60
+ */
61
+ onError?: (event: Event) => void;
62
+ /**
63
+ * Callback when a message is received.
64
+ */
65
+ onMessage?: (event: MessageEvent) => void;
66
+ }
67
+ interface UseWebSocketReturn<T = unknown> {
68
+ /**
69
+ * Current connection status.
70
+ */
71
+ status: WebSocketStatus;
72
+ /**
73
+ * Last received message (parsed as JSON if possible).
74
+ */
75
+ lastMessage: T | null;
76
+ /**
77
+ * Send a message through the WebSocket.
78
+ */
79
+ send: (data: string | object) => void;
80
+ /**
81
+ * Manually connect to the WebSocket.
82
+ */
83
+ connect: () => void;
84
+ /**
85
+ * Manually disconnect from the WebSocket.
86
+ */
87
+ disconnect: () => void;
88
+ }
89
+ /**
90
+ * Hook for managing WebSocket connections with auto-reconnect.
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * const { status, lastMessage, send } = useWebSocket<LogEntry>(
95
+ * 'ws://localhost:3000/ws',
96
+ * {
97
+ * onMessage: (event) => console.log('Received:', event.data),
98
+ * }
99
+ * );
100
+ *
101
+ * // Send a message
102
+ * send({ type: 'subscribe', channel: 'logs' });
103
+ *
104
+ * // Check connection status
105
+ * if (status === 'connected') {
106
+ * // ...
107
+ * }
108
+ * ```
109
+ */
110
+ declare function useWebSocket<T = unknown>(url: string | null, options?: UseWebSocketOptions): UseWebSocketReturn<T>;
111
+ //#endregion
112
+ export { UseWebSocketOptions, UseWebSocketReturn, WebSocketStatus, useDebounce, useLocalStorage, useWebSocket };
113
+ //# sourceMappingURL=index-DmtSyJ1q.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DmtSyJ1q.d.mts","names":[],"sources":["../src/hooks/use-debounce.ts","../src/hooks/use-local-storage.ts","../src/hooks/use-websocket.ts"],"sourcesContent":[],"mappings":";;AAgBA;;;;AAA0D;;;;ACH1D;;;;;AAG2B,iBDAX,WCAW,CAAA,CAAA,CAAA,CAAA,KAAA,EDAW,CCAX,EAAA,KAAA,EAAA,MAAA,CAAA,EDA8B,CCA9B;;;;ADA3B;;;;AAA0D;;;;ACH1D;;AAEe,iBAFC,eAED,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,MAAA,EAAA,YAAA,EAAA,CAAA,CAAA,EAAA,CACX,CADW,EAAA,CAAA,KAAA,EACA,CADA,GAAA,CAAA,CAAA,IAAA,EACY,CADZ,EAAA,GACkB,CADlB,CAAA,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,IAAA,CAAA;;;KCbH,eAAA;AFcI,UEZC,mBAAA,CFYU;EAAA;;;AAA+B;;;;ACH1D;;EAA+B,cAEhB,CAAA,EAAA,MAAA;EAAC;;;;EACkB,oBAAA,CAAA,EAAA,MAAA;;;;ECdtB,MAAA,CAAA,EAAA,CAAA,KAAA,EAqBM,KArBS,EAAA,GAAA,IAAA;EAEV;;;EAmBM,OAIJ,CAAA,EAAA,CAAA,KAAA,EAAA,UAAA,EAAA,GAAA,IAAA;EAAU;;AAQI;EAGhB,OAAA,CAAA,EAAA,CAAA,KAAA,EAPE,KAOgB,EAAA,GAAA,IAAA;EAAA;;;EAQpB,SAAA,CAAA,EAAA,CAAA,KAAA,EAXM,YAWN,EAAA,GAAA,IAAA;AAoCf;AAA4B,UA5CX,kBA4CW,CAAA,IAAA,OAAA,CAAA,CAAA;EAAA;;;EAGP,MAAA,EA3CZ,eA2CY;;;;eAvCP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCE,wDAEN,sBACP,mBAAmB"}