tona-hooks 1.0.1 → 1.0.18

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dispatch, EffectCallback, useLayoutEffect } from "preact/hooks";
1
+ import { Dispatch, EffectCallback, useEffect } from "preact/hooks";
2
2
  import { SetStateAction } from "preact/compat";
3
3
  import { RefObject } from "preact";
4
4
 
@@ -25,7 +25,7 @@ declare function useEventCallback<Args extends unknown[], R>(fn: (...args: Args)
25
25
  declare function useEventCallback<Args extends unknown[], R>(fn: ((...args: Args) => R) | undefined): ((...args: Args) => R) | undefined;
26
26
  //#endregion
27
27
  //#region src/use-isomorphic-layout-effect.d.ts
28
- declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
28
+ declare const useIsomorphicLayoutEffect: typeof useEffect;
29
29
  //#endregion
30
30
  //#region src/use-query-dom.d.ts
31
31
  interface UseQueryDomOptions<T> {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- let preact_hooks = require("preact/hooks");
2
- let preact_compat = require("preact/compat");
1
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
2
+ import { useCallback as useCallback$1, useRef as useRef$1 } from "preact/compat";
3
3
 
4
4
  //#region src/use-ajax-complete.ts
5
5
  /**
@@ -10,7 +10,7 @@ let preact_compat = require("preact/compat");
10
10
  * @param config.onError 错误时的回调函数
11
11
  */
12
12
  function useAjaxComplete(config) {
13
- (0, preact_hooks.useEffect)(() => {
13
+ useEffect(() => {
14
14
  const { urlPattern, onSuccess, onError } = config;
15
15
  const handleAjaxComplete = (_, jqXHR, option) => {
16
16
  const url = option?.url;
@@ -31,77 +31,49 @@ function useAjaxComplete(config) {
31
31
  //#endregion
32
32
  //#region src/use-effect-once.ts
33
33
  const useEffectOnce = (effect) => {
34
- (0, preact_hooks.useEffect)(effect, []);
34
+ useEffect(effect, []);
35
35
  };
36
36
 
37
37
  //#endregion
38
38
  //#region src/use-isomorphic-layout-effect.ts
39
- const useIsomorphicLayoutEffect = typeof window !== "undefined" ? preact_hooks.useLayoutEffect : preact_hooks.useEffect;
39
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
40
40
 
41
41
  //#endregion
42
42
  //#region src/use-event-callback.ts
43
43
  function useEventCallback(fn) {
44
- const ref = (0, preact_compat.useRef)(() => {
44
+ const ref = useRef$1(() => {
45
45
  throw new Error("Cannot call an event handler while rendering.");
46
46
  });
47
47
  useIsomorphicLayoutEffect(() => {
48
48
  ref.current = fn;
49
49
  }, [fn]);
50
- return (0, preact_compat.useCallback)((...args) => ref.current?.(...args), [ref]);
50
+ return useCallback$1((...args) => ref.current?.(...args), [ref]);
51
51
  }
52
52
 
53
53
  //#endregion
54
54
  //#region src/use-query-dom.ts
55
55
  function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
56
- const [data, setData] = (0, preact_hooks.useState)(null);
57
- const [isPending, setIsPending] = (0, preact_hooks.useState)(false);
58
- const queryFnRef = (0, preact_hooks.useRef)(queryFn);
59
- const observerRef = (0, preact_hooks.useRef)(null);
60
- const ajaxStartRef = (0, preact_hooks.useRef)(0);
61
- const debug = selector === "#user_icon.navbar-avatar" && (() => {
62
- try {
63
- return globalThis.localStorage.getItem("tona-debug-avatar") === "1";
64
- } catch {
65
- return false;
66
- }
67
- })();
68
- (0, preact_hooks.useEffect)(() => {
56
+ const [data, setData] = useState(null);
57
+ const [isPending, setIsPending] = useState(false);
58
+ const queryFnRef = useRef(queryFn);
59
+ const observerRef = useRef(null);
60
+ const ajaxStartRef = useRef(0);
61
+ useEffect(() => {
69
62
  queryFnRef.current = queryFn;
70
63
  }, [queryFn]);
71
- const queryElement = (0, preact_hooks.useCallback)(() => {
64
+ const queryElement = useCallback(() => {
72
65
  const element = document.querySelector(selector);
73
66
  const nextData = queryFnRef.current(element);
74
67
  setData((prev) => {
75
68
  if (Object.is(prev, nextData)) return prev;
76
69
  return nextData;
77
70
  });
78
- if (debug) console.log("[useQueryDOM]", {
79
- selector,
80
- elementFound: Boolean(element),
81
- nextData,
82
- time: (/* @__PURE__ */ new Date()).toISOString()
83
- });
84
- }, [debug, selector]);
85
- (0, preact_hooks.useEffect)(() => {
71
+ }, [selector]);
72
+ useEffect(() => {
86
73
  queryElement();
87
74
  if (!observe) return;
88
75
  const targetNode = document.querySelector(selector)?.parentElement || document.body;
89
- const observer = new MutationObserver((records) => {
90
- if (debug) {
91
- const summary = records.map((r) => ({
92
- type: r.type,
93
- target: r.target instanceof Element ? r.target.tagName : "unknown",
94
- attributeName: r.attributeName || null,
95
- addedNodes: r.addedNodes.length,
96
- removedNodes: r.removedNodes.length
97
- }));
98
- console.log("[useQueryDOM:mutation]", {
99
- selector,
100
- summary
101
- });
102
- }
103
- queryElement();
104
- });
76
+ const observer = new MutationObserver(queryElement);
105
77
  observerRef.current = observer;
106
78
  observer.observe(targetNode, {
107
79
  childList: true,
@@ -114,12 +86,11 @@ function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
114
86
  observerRef.current = null;
115
87
  };
116
88
  }, [
117
- debug,
118
89
  observe,
119
90
  queryElement,
120
91
  selector
121
92
  ]);
122
- (0, preact_hooks.useEffect)(() => {
93
+ useEffect(() => {
123
94
  if (!ajaxUrl) return;
124
95
  const urls = Array.isArray(ajaxUrl) ? ajaxUrl : [ajaxUrl];
125
96
  let timeoutId = null;
@@ -183,7 +154,7 @@ function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
183
154
  //#endregion
184
155
  //#region src/use-unmount.ts
185
156
  const useUnmount = (fn) => {
186
- const fnRef = (0, preact_hooks.useRef)(fn);
157
+ const fnRef = useRef(fn);
187
158
  fnRef.current = fn;
188
159
  useEffectOnce(() => () => fnRef.current());
189
160
  };
@@ -191,9 +162,9 @@ const useUnmount = (fn) => {
191
162
  //#endregion
192
163
  //#region src/use-raf-state.ts
193
164
  const useRafState = (initialState) => {
194
- const frame = (0, preact_hooks.useRef)(0);
195
- const [state, setState] = (0, preact_hooks.useState)(initialState);
196
- const setRafState = (0, preact_hooks.useCallback)((value) => {
165
+ const frame = useRef(0);
166
+ const [state, setState] = useState(initialState);
167
+ const setRafState = useCallback((value) => {
197
168
  cancelAnimationFrame(frame.current);
198
169
  frame.current = requestAnimationFrame(() => {
199
170
  setState(value);
@@ -218,14 +189,12 @@ const isBrowser = typeof window !== "undefined";
218
189
  //#endregion
219
190
  //#region src/use-scroll.ts
220
191
  const useScroll = (ref) => {
221
- if (process.env.NODE_ENV === "development") {
222
- if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
223
- }
192
+ if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
224
193
  const [state, setState] = useRafState({
225
194
  x: 0,
226
195
  y: 0
227
196
  });
228
- (0, preact_hooks.useEffect)(() => {
197
+ useEffect(() => {
229
198
  const handler = () => {
230
199
  if (ref.current) setState({
231
200
  x: ref.current.scrollLeft,
@@ -250,7 +219,7 @@ const useWindowScroll = () => {
250
219
  x: isBrowser ? window.pageXOffset : 0,
251
220
  y: isBrowser ? window.pageYOffset : 0
252
221
  }));
253
- (0, preact_hooks.useEffect)(() => {
222
+ useEffect(() => {
254
223
  const handler = () => {
255
224
  setState((state$1) => {
256
225
  const { pageXOffset, pageYOffset } = window;
@@ -273,12 +242,4 @@ const useWindowScroll = () => {
273
242
  };
274
243
 
275
244
  //#endregion
276
- exports.useAjaxComplete = useAjaxComplete;
277
- exports.useEffectOnce = useEffectOnce;
278
- exports.useEventCallback = useEventCallback;
279
- exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
280
- exports.useQueryDOM = useQueryDOM;
281
- exports.useRafState = useRafState;
282
- exports.useScroll = useScroll;
283
- exports.useUnmount = useUnmount;
284
- exports.useWindowScroll = useWindowScroll;
245
+ export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tona-hooks",
3
- "version": "1.0.1",
3
+ "version": "1.0.18",
4
4
  "description": "",
5
5
  "author": {
6
6
  "name": "guangzan",
@@ -8,25 +8,26 @@
8
8
  "email": "guangzan1999@outlook.com"
9
9
  },
10
10
  "license": "MIT",
11
- "homepage": "https://github.com/acnblogs/hooks#readme",
11
+ "homepage": "https://github.com/guangzan/tona/tree/main/packages/hooks#readme",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "git+https://github.com/acnblogs/hooks.git"
14
+ "url": "git+https://github.com/guangzan/tona.git",
15
+ "directory": "packages/hooks"
15
16
  },
16
17
  "bugs": {
17
- "url": "https://github.com/acnblogs/hooks/issues"
18
+ "url": "https://github.com/guangzan/tona/issues"
18
19
  },
19
20
  "keywords": [
20
21
  "博客园"
21
22
  ],
23
+ "type": "module",
22
24
  "exports": {
23
25
  ".": {
24
26
  "types": "./dist/index.d.ts",
25
- "import": "./dist/index.mjs",
26
- "require": "./dist/index.js"
27
+ "import": "./dist/index.js"
27
28
  }
28
29
  },
29
- "main": "./dist/index.mjs",
30
+ "main": "./dist/index.js",
30
31
  "module": "./dist/index.js",
31
32
  "types": "./dist/index.d.ts",
32
33
  "files": [
package/dist/index.d.mts DELETED
@@ -1,71 +0,0 @@
1
- import { Dispatch, EffectCallback, useLayoutEffect } from "preact/hooks";
2
- import { SetStateAction } from "preact/compat";
3
- import { RefObject } from "preact";
4
-
5
- //#region src/use-ajax-complete.d.ts
6
-
7
- /**
8
- * 通用的 Ajax 完成监听 Hook
9
- * @param config 配置对象
10
- * @param config.urlPattern 要监听的 URL 模式(支持字符串包含匹配)
11
- * @param config.onSuccess 成功时的回调函数
12
- * @param config.onError 错误时的回调函数
13
- */
14
- declare function useAjaxComplete(config: {
15
- urlPattern: string | string[];
16
- onSuccess?: (response: any, jqXHR: JQuery.jqXHR, option: JQuery.AjaxSettings) => void;
17
- onError?: (response: any, jqXHR: JQuery.jqXHR, option: JQuery.AjaxSettings) => void;
18
- }): void;
19
- //#endregion
20
- //#region src/use-effect-once.d.ts
21
- declare const useEffectOnce: (effect: EffectCallback) => void;
22
- //#endregion
23
- //#region src/use-event-callback.d.ts
24
- declare function useEventCallback<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R;
25
- declare function useEventCallback<Args extends unknown[], R>(fn: ((...args: Args) => R) | undefined): ((...args: Args) => R) | undefined;
26
- //#endregion
27
- //#region src/use-isomorphic-layout-effect.d.ts
28
- declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
29
- //#endregion
30
- //#region src/use-query-dom.d.ts
31
- interface UseQueryDomOptions<T> {
32
- selector: string;
33
- observe?: boolean;
34
- queryFn: (el: Element | null) => T | null;
35
- /**
36
- * 监听的 selector 的 DOM 相关的 AJAX 请求 URL
37
- */
38
- ajaxUrl?: string | string[];
39
- }
40
- interface UseQueryDomResult<T> {
41
- data: T | null;
42
- isPending: boolean;
43
- }
44
- declare function useQueryDOM<T>({
45
- selector,
46
- observe,
47
- queryFn,
48
- ajaxUrl
49
- }: UseQueryDomOptions<T>): UseQueryDomResult<T>;
50
- //#endregion
51
- //#region src/use-raf-state.d.ts
52
- declare const useRafState: <S>(initialState: S | (() => S)) => [S, Dispatch<SetStateAction<S>>];
53
- //#endregion
54
- //#region src/use-scroll.d.ts
55
- interface State$1 {
56
- x: number;
57
- y: number;
58
- }
59
- declare const useScroll: (ref: RefObject<HTMLElement>) => State$1;
60
- //#endregion
61
- //#region src/use-unmount.d.ts
62
- declare const useUnmount: (fn: () => any) => void;
63
- //#endregion
64
- //#region src/use-window-scroll.d.ts
65
- interface State {
66
- x: number;
67
- y: number;
68
- }
69
- declare const useWindowScroll: () => State;
70
- //#endregion
71
- export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
package/dist/index.mjs DELETED
@@ -1,274 +0,0 @@
1
- import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
2
- import { useCallback as useCallback$1, useRef as useRef$1 } from "preact/compat";
3
-
4
- //#region src/use-ajax-complete.ts
5
- /**
6
- * 通用的 Ajax 完成监听 Hook
7
- * @param config 配置对象
8
- * @param config.urlPattern 要监听的 URL 模式(支持字符串包含匹配)
9
- * @param config.onSuccess 成功时的回调函数
10
- * @param config.onError 错误时的回调函数
11
- */
12
- function useAjaxComplete(config) {
13
- useEffect(() => {
14
- const { urlPattern, onSuccess, onError } = config;
15
- const handleAjaxComplete = (_, jqXHR, option) => {
16
- const url = option?.url;
17
- if (!url) return;
18
- if (!(Array.isArray(urlPattern) ? urlPattern : [urlPattern]).some((pattern) => url.includes(pattern))) return;
19
- const response = jqXHR.responseJSON || jqXHR.responseText;
20
- const hasError = jqXHR.status >= 400;
21
- if (hasError && onError) onError(response, jqXHR, option);
22
- else if (!hasError && onSuccess) onSuccess(response, jqXHR, option);
23
- };
24
- $(document).on("ajaxComplete", handleAjaxComplete);
25
- return () => {
26
- $(document).off("ajaxComplete", handleAjaxComplete);
27
- };
28
- }, [config]);
29
- }
30
-
31
- //#endregion
32
- //#region src/use-effect-once.ts
33
- const useEffectOnce = (effect) => {
34
- useEffect(effect, []);
35
- };
36
-
37
- //#endregion
38
- //#region src/use-isomorphic-layout-effect.ts
39
- const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
40
-
41
- //#endregion
42
- //#region src/use-event-callback.ts
43
- function useEventCallback(fn) {
44
- const ref = useRef$1(() => {
45
- throw new Error("Cannot call an event handler while rendering.");
46
- });
47
- useIsomorphicLayoutEffect(() => {
48
- ref.current = fn;
49
- }, [fn]);
50
- return useCallback$1((...args) => ref.current?.(...args), [ref]);
51
- }
52
-
53
- //#endregion
54
- //#region src/use-query-dom.ts
55
- function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
56
- const [data, setData] = useState(null);
57
- const [isPending, setIsPending] = useState(false);
58
- const queryFnRef = useRef(queryFn);
59
- const observerRef = useRef(null);
60
- const ajaxStartRef = useRef(0);
61
- const debug = selector === "#user_icon.navbar-avatar" && (() => {
62
- try {
63
- return globalThis.localStorage.getItem("tona-debug-avatar") === "1";
64
- } catch {
65
- return false;
66
- }
67
- })();
68
- useEffect(() => {
69
- queryFnRef.current = queryFn;
70
- }, [queryFn]);
71
- const queryElement = useCallback(() => {
72
- const element = document.querySelector(selector);
73
- const nextData = queryFnRef.current(element);
74
- setData((prev) => {
75
- if (Object.is(prev, nextData)) return prev;
76
- return nextData;
77
- });
78
- if (debug) console.log("[useQueryDOM]", {
79
- selector,
80
- elementFound: Boolean(element),
81
- nextData,
82
- time: (/* @__PURE__ */ new Date()).toISOString()
83
- });
84
- }, [debug, selector]);
85
- useEffect(() => {
86
- queryElement();
87
- if (!observe) return;
88
- const targetNode = document.querySelector(selector)?.parentElement || document.body;
89
- const observer = new MutationObserver((records) => {
90
- if (debug) {
91
- const summary = records.map((r) => ({
92
- type: r.type,
93
- target: r.target instanceof Element ? r.target.tagName : "unknown",
94
- attributeName: r.attributeName || null,
95
- addedNodes: r.addedNodes.length,
96
- removedNodes: r.removedNodes.length
97
- }));
98
- console.log("[useQueryDOM:mutation]", {
99
- selector,
100
- summary
101
- });
102
- }
103
- queryElement();
104
- });
105
- observerRef.current = observer;
106
- observer.observe(targetNode, {
107
- childList: true,
108
- subtree: true,
109
- attributes: true,
110
- characterData: false
111
- });
112
- return () => {
113
- observer.disconnect();
114
- observerRef.current = null;
115
- };
116
- }, [
117
- debug,
118
- observe,
119
- queryElement,
120
- selector
121
- ]);
122
- useEffect(() => {
123
- if (!ajaxUrl) return;
124
- const urls = Array.isArray(ajaxUrl) ? ajaxUrl : [ajaxUrl];
125
- let timeoutId = null;
126
- const pendingRequests = /* @__PURE__ */ new Set();
127
- const clearPending = () => {
128
- setIsPending(false);
129
- if (timeoutId) {
130
- clearTimeout(timeoutId);
131
- timeoutId = null;
132
- }
133
- };
134
- const checkAllRequestsComplete = () => {
135
- if (pendingRequests.size === 0) clearPending();
136
- };
137
- const handleAjaxSend = (_, __, ajaxOptions) => {
138
- const url = ajaxOptions?.url || "";
139
- if (urls.some((targetUrl) => url.includes(targetUrl))) {
140
- pendingRequests.add(url);
141
- setIsPending(true);
142
- ajaxStartRef.current = Date.now();
143
- if (timeoutId) clearTimeout(timeoutId);
144
- timeoutId = window.setTimeout(() => {
145
- pendingRequests.delete(url);
146
- checkAllRequestsComplete();
147
- }, 1e4);
148
- }
149
- };
150
- const handleAjaxComplete = (_, __, ajaxOptions) => {
151
- const url = ajaxOptions?.url || "";
152
- if (urls.some((targetUrl) => url.includes(targetUrl))) {
153
- pendingRequests.delete(url);
154
- setTimeout(() => {
155
- checkAllRequestsComplete();
156
- }, 50);
157
- }
158
- };
159
- const handleAjaxError = (_, __, ajaxOptions) => {
160
- const url = ajaxOptions?.url || "";
161
- if (urls.some((targetUrl) => url.includes(targetUrl))) {
162
- pendingRequests.delete(url);
163
- checkAllRequestsComplete();
164
- }
165
- };
166
- $(document).ajaxSend(handleAjaxSend);
167
- $(document).ajaxComplete(handleAjaxComplete);
168
- $(document).ajaxError(handleAjaxError);
169
- return () => {
170
- $(document).off("ajaxSend", handleAjaxSend);
171
- $(document).off("ajaxComplete", handleAjaxComplete);
172
- $(document).off("ajaxError", handleAjaxError);
173
- if (timeoutId) clearTimeout(timeoutId);
174
- pendingRequests.clear();
175
- };
176
- }, [ajaxUrl]);
177
- return {
178
- data,
179
- isPending
180
- };
181
- }
182
-
183
- //#endregion
184
- //#region src/use-unmount.ts
185
- const useUnmount = (fn) => {
186
- const fnRef = useRef(fn);
187
- fnRef.current = fn;
188
- useEffectOnce(() => () => fnRef.current());
189
- };
190
-
191
- //#endregion
192
- //#region src/use-raf-state.ts
193
- const useRafState = (initialState) => {
194
- const frame = useRef(0);
195
- const [state, setState] = useState(initialState);
196
- const setRafState = useCallback((value) => {
197
- cancelAnimationFrame(frame.current);
198
- frame.current = requestAnimationFrame(() => {
199
- setState(value);
200
- });
201
- }, []);
202
- useUnmount(() => {
203
- cancelAnimationFrame(frame.current);
204
- });
205
- return [state, setRafState];
206
- };
207
-
208
- //#endregion
209
- //#region src/misc/util.ts
210
- function on(obj, ...args) {
211
- if (obj?.addEventListener) obj.addEventListener(...args);
212
- }
213
- function off(obj, ...args) {
214
- if (obj?.removeEventListener) obj.removeEventListener(...args);
215
- }
216
- const isBrowser = typeof window !== "undefined";
217
-
218
- //#endregion
219
- //#region src/use-scroll.ts
220
- const useScroll = (ref) => {
221
- if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
222
- const [state, setState] = useRafState({
223
- x: 0,
224
- y: 0
225
- });
226
- useEffect(() => {
227
- const handler = () => {
228
- if (ref.current) setState({
229
- x: ref.current.scrollLeft,
230
- y: ref.current.scrollTop
231
- });
232
- };
233
- if (ref.current) on(ref.current, "scroll", handler, {
234
- capture: false,
235
- passive: true
236
- });
237
- return () => {
238
- if (ref.current) off(ref.current, "scroll", handler);
239
- };
240
- }, [ref, setState]);
241
- return state;
242
- };
243
-
244
- //#endregion
245
- //#region src/use-window-scroll.ts
246
- const useWindowScroll = () => {
247
- const [state, setState] = useRafState(() => ({
248
- x: isBrowser ? window.pageXOffset : 0,
249
- y: isBrowser ? window.pageYOffset : 0
250
- }));
251
- useEffect(() => {
252
- const handler = () => {
253
- setState((state$1) => {
254
- const { pageXOffset, pageYOffset } = window;
255
- return state$1.x !== pageXOffset || state$1.y !== pageYOffset ? {
256
- x: pageXOffset,
257
- y: pageYOffset
258
- } : state$1;
259
- });
260
- };
261
- handler();
262
- on(window, "scroll", handler, {
263
- capture: false,
264
- passive: true
265
- });
266
- return () => {
267
- off(window, "scroll", handler);
268
- };
269
- }, [setState]);
270
- return state;
271
- };
272
-
273
- //#endregion
274
- export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };