sse-hooks 1.0.0 → 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.
package/dist/index.mjs CHANGED
@@ -18,6 +18,150 @@ function useBoolean(defaultValue = false) {
18
18
  return { value, setValue, setTrue, setFalse, toggle };
19
19
  }
20
20
 
21
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
22
+
23
+ function useEventListener(eventName, handler, element, options) {
24
+ const savedHandler = useRef(handler);
25
+ useIsomorphicLayoutEffect(() => {
26
+ savedHandler.current = handler;
27
+ }, [handler]);
28
+ useEffect(() => {
29
+ const targetElement = element?.current ?? window;
30
+ if (!(targetElement && targetElement.addEventListener)) return;
31
+ const listener = (event) => {
32
+ savedHandler.current(event);
33
+ };
34
+ targetElement.addEventListener(eventName, listener, options);
35
+ return () => {
36
+ targetElement.removeEventListener(eventName, listener, options);
37
+ };
38
+ }, [eventName, element, options]);
39
+ }
40
+
41
+ function useClickAnyWhere(handler) {
42
+ useEventListener("click", (event) => {
43
+ handler(event);
44
+ });
45
+ }
46
+
47
+ function useEventCallback(fn) {
48
+ const ref = useRef(() => {
49
+ throw new Error("Cannot call an event handler while rendering.");
50
+ });
51
+ useIsomorphicLayoutEffect(() => {
52
+ ref.current = fn;
53
+ }, [fn]);
54
+ return useCallback((...args) => ref.current?.(...args), [ref]);
55
+ }
56
+
57
+ const IS_SERVER$7 = typeof document === "undefined";
58
+ function parseCookies() {
59
+ if (IS_SERVER$7) return {};
60
+ return document.cookie.split("; ").reduce(
61
+ (acc, part) => {
62
+ const [k, ...v] = part.split("=");
63
+ if (k && v) {
64
+ acc[decodeURIComponent(k.trim())] = decodeURIComponent(v.join("="));
65
+ }
66
+ return acc;
67
+ },
68
+ {}
69
+ );
70
+ }
71
+ function buildCookie(key, value, options) {
72
+ let cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
73
+ if (options.path) cookie += `; path=${options.path}`;
74
+ if (options.domain) cookie += `; domain=${options.domain}`;
75
+ if (options.expires) cookie += `; expires=${options.expires.toUTCString()}`;
76
+ if (options.maxAge) cookie += `; max-age=${options.maxAge}`;
77
+ if (options.secure) cookie += `; secure`;
78
+ if (options.sameSite) cookie += `; samesite=${options.sameSite}`;
79
+ return cookie;
80
+ }
81
+ function useCookie(key, initialValue, options = {}) {
82
+ const { initializeWithValue = true, prefix = "" } = options;
83
+ const cookieKey = prefix + key;
84
+ const serializer = useCallback(
85
+ (value) => {
86
+ if (options.serializer) return options.serializer(value);
87
+ return JSON.stringify(value);
88
+ },
89
+ [options]
90
+ );
91
+ const deserializer = useCallback(
92
+ (value) => {
93
+ if (options.deserializer) return options.deserializer(value);
94
+ if (value === "undefined") return void 0;
95
+ const fallback = initialValue instanceof Function ? initialValue() : initialValue;
96
+ try {
97
+ return JSON.parse(value);
98
+ } catch {
99
+ return fallback;
100
+ }
101
+ },
102
+ [options, initialValue]
103
+ );
104
+ const readValue = useCallback(() => {
105
+ const fallback = initialValue instanceof Function ? initialValue() : initialValue;
106
+ if (IS_SERVER$7) return fallback;
107
+ const cookies = parseCookies();
108
+ if (!(cookieKey in cookies)) return fallback;
109
+ return deserializer(cookies[cookieKey]);
110
+ }, [cookieKey, deserializer, initialValue]);
111
+ const [storedValue, setStoredValue] = useState(() => {
112
+ if (initializeWithValue) return readValue();
113
+ return initialValue instanceof Function ? initialValue() : initialValue;
114
+ });
115
+ const setValue = useEventCallback((value) => {
116
+ if (IS_SERVER$7) return;
117
+ try {
118
+ const newValue = value instanceof Function ? value(readValue()) : value;
119
+ const serialized = serializer(newValue);
120
+ document.cookie = buildCookie(cookieKey, serialized, {
121
+ path: "/",
122
+ ...options
123
+ });
124
+ setStoredValue(newValue);
125
+ window.dispatchEvent(
126
+ new CustomEvent("cookie-change", { detail: { key: cookieKey } })
127
+ );
128
+ } catch (error) {
129
+ console.warn(`Error setting cookie "${cookieKey}":`, error);
130
+ }
131
+ });
132
+ const removeValue = useEventCallback(() => {
133
+ if (IS_SERVER$7) return;
134
+ const fallback = initialValue instanceof Function ? initialValue() : initialValue;
135
+ document.cookie = buildCookie(cookieKey, "", {
136
+ path: "/",
137
+ ...options,
138
+ expires: /* @__PURE__ */ new Date(0)
139
+ });
140
+ setStoredValue(fallback);
141
+ window.dispatchEvent(
142
+ new CustomEvent("cookie-change", { detail: { key: cookieKey } })
143
+ );
144
+ });
145
+ useEffect(() => {
146
+ setStoredValue(readValue());
147
+ }, [cookieKey]);
148
+ const handleChange = useCallback(
149
+ (event) => {
150
+ if ("detail" in event && event.detail?.key !== cookieKey) return;
151
+ if ("key" in event && event.key !== cookieKey) return;
152
+ setStoredValue(readValue());
153
+ },
154
+ [cookieKey, readValue]
155
+ );
156
+ useEventListener("cookie-change", handleChange);
157
+ useEventListener("visibilitychange", () => {
158
+ if (document.visibilityState === "visible") {
159
+ setStoredValue(readValue());
160
+ }
161
+ });
162
+ return [storedValue, setValue, removeValue];
163
+ }
164
+
21
165
  function useCopyToClipboard() {
22
166
  const [copiedText, setCopiedText] = useState(null);
23
167
  const copy = useCallback(async (text) => {
@@ -58,8 +202,6 @@ function useCounter(initialValue) {
58
202
  };
59
203
  }
60
204
 
61
- const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
62
-
63
205
  function useInterval(callback, delay) {
64
206
  const savedCallback = useRef(callback);
65
207
  useIsomorphicLayoutEffect(() => {
@@ -114,34 +256,6 @@ function useCountdown({
114
256
  return [count, { startCountdown, stopCountdown, resetCountdown }];
115
257
  }
116
258
 
117
- function useEventCallback(fn) {
118
- const ref = useRef(() => {
119
- throw new Error("Cannot call an event handler while rendering.");
120
- });
121
- useIsomorphicLayoutEffect(() => {
122
- ref.current = fn;
123
- }, [fn]);
124
- return useCallback((...args) => ref.current?.(...args), [ref]);
125
- }
126
-
127
- function useEventListener(eventName, handler, element, options) {
128
- const savedHandler = useRef(handler);
129
- useIsomorphicLayoutEffect(() => {
130
- savedHandler.current = handler;
131
- }, [handler]);
132
- useEffect(() => {
133
- const targetElement = element?.current ?? window;
134
- if (!(targetElement && targetElement.addEventListener)) return;
135
- const listener = (event) => {
136
- savedHandler.current(event);
137
- };
138
- targetElement.addEventListener(eventName, listener, options);
139
- return () => {
140
- targetElement.removeEventListener(eventName, listener, options);
141
- };
142
- }, [eventName, element, options]);
143
- }
144
-
145
259
  const IS_SERVER$6 = typeof window === "undefined";
146
260
  function useLocalStorage(key, initialValue, options = {}) {
147
261
  const { initializeWithValue = true } = options;
@@ -276,7 +390,7 @@ function useMediaQuery(query, {
276
390
  }
277
391
 
278
392
  const COLOR_SCHEME_QUERY$1 = "(prefers-color-scheme: dark)";
279
- const LOCAL_STORAGE_KEY$1 = "usehooks-ts-dark-mode";
393
+ const LOCAL_STORAGE_KEY$1 = "sse-hooks-dark-mode";
280
394
  function useDarkMode(options = {}) {
281
395
  const {
282
396
  defaultValue,
@@ -1104,23 +1218,21 @@ function useSessionStorage(key, initialValue, options = {}) {
1104
1218
  }
1105
1219
  return initialValue instanceof Function ? initialValue() : initialValue;
1106
1220
  });
1107
- const setValue = useEventCallback(
1108
- (value) => {
1109
- if (IS_SERVER$1) {
1110
- console.warn(
1111
- `Tried setting sessionStorage key \u201C${key}\u201D even though environment is not a client`
1112
- );
1113
- }
1114
- try {
1115
- const newValue = value instanceof Function ? value(readValue()) : value;
1116
- window.sessionStorage.setItem(key, serializer(newValue));
1117
- setStoredValue(newValue);
1118
- window.dispatchEvent(new StorageEvent("session-storage", { key }));
1119
- } catch (error) {
1120
- console.warn(`Error setting sessionStorage key \u201C${key}\u201D:`, error);
1121
- }
1221
+ const setValue = useEventCallback((value) => {
1222
+ if (IS_SERVER$1) {
1223
+ console.warn(
1224
+ `Tried setting sessionStorage key \u201C${key}\u201D even though environment is not a client`
1225
+ );
1122
1226
  }
1123
- );
1227
+ try {
1228
+ const newValue = value instanceof Function ? value(readValue()) : value;
1229
+ window.sessionStorage.setItem(key, serializer(newValue));
1230
+ setStoredValue(newValue);
1231
+ window.dispatchEvent(new StorageEvent("session-storage", { key }));
1232
+ } catch (error) {
1233
+ console.warn(`Error setting sessionStorage key \u201C${key}\u201D:`, error);
1234
+ }
1235
+ });
1124
1236
  const removeValue = useEventCallback(() => {
1125
1237
  if (IS_SERVER$1) {
1126
1238
  console.warn(
@@ -1191,7 +1303,7 @@ function useStep(maxStep) {
1191
1303
  }
1192
1304
 
1193
1305
  const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)";
1194
- const LOCAL_STORAGE_KEY = "usehooks-ts-ternary-dark-mode";
1306
+ const LOCAL_STORAGE_KEY = "sse-hooks-ternary-dark-mode";
1195
1307
  function useTernaryDarkMode({
1196
1308
  defaultValue = "system",
1197
1309
  localStorageKey = LOCAL_STORAGE_KEY,
@@ -1279,4 +1391,4 @@ function useWindowSize(options = {}) {
1279
1391
  return windowSize;
1280
1392
  }
1281
1393
 
1282
- export { useBoolean, useCopyToClipboard, useCountdown, useCounter, useDarkMode, useDebounceCallback, useDebounceValue, useDelete, useDocumentTitle, useEventCallback, useEventListener, useFetch, useGet, useHover, useIndexedDB, useIntersectionObserver, useInterval, useIsClient, useIsMounted, useIsomorphicLayoutEffect, useLocalStorage, useMap, useMediaQuery, usePost, usePut, useReadLocalStorage, useResizeObserver, useScreen, useScript, useScrollLock, useSessionStorage, useStep, useTernaryDarkMode, useTimeout, useToggle, useUnmount, useWindowSize };
1394
+ export { useBoolean, useClickAnyWhere, useCookie, useCopyToClipboard, useCountdown, useCounter, useDarkMode, useDebounceCallback, useDebounceValue, useDelete, useDocumentTitle, useEventCallback, useEventListener, useFetch, useGet, useHover, useIndexedDB, useIntersectionObserver, useInterval, useIsClient, useIsMounted, useIsomorphicLayoutEffect, useLocalStorage, useMap, useMediaQuery, usePost, usePut, useReadLocalStorage, useResizeObserver, useScreen, useScript, useScrollLock, useSessionStorage, useStep, useTernaryDarkMode, useTimeout, useToggle, useUnmount, useWindowSize };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sse-hooks",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "React hook library, ready to use, written in Typescript.",
5
5
  "license": "MIT",
6
6
  "author": "SSE World",